unity3d 取决于接触点的桨叶反射球

pnwntuvh  于 2022-12-30  发布在  其他
关注(0)|答案(1)|浏览(144)

当打桨球是反弹奇怪。

private Vector3 direction;

private void Start()
{
    direction = transform.up;
}

private void FixedUpdate()
{
    transform.Translate(direction * (Time.deltaTime * BallManager.Instance.initialBallSpeed));
}

private void OnCollisionEnter(Collision col)
{
    if (col.gameObject.CompareTag("Paddle"))
    {
        var cp = col.contacts[0];
        direction = Vector2.Reflect(direction, PaddleScript.Instance.transform.position.normalized);
    }
}

我想使反弹总是以相同的力量向上和向一侧取决于命中点。

jmo0nnb3

jmo0nnb31#

首先,当使用物理时,你根本不应该通过Transform
您甚至根本不需要此组件...为什么不简单地

  • 消除所有重力(Gravity Scale-〉0
  • 消除所有阻力(Linear Drag-〉0
  • 在球和/或桨式碰撞器上放置适当的PhysicsMaterial2D,并将bounciness设置为1,将摩擦力设置为0

=〉默认情况下,它应该已经按照预期运行。
否则我会将您的代码更改为

[SerializeField] private Rigidbody2D rigidbody;
private Vector3 direction;

private void Start()
{
    if(!rigidbody) rigidbody= GetComponent<Rigidbody2D>();
    direction = transform.up;
}

private void FixedUpdate()
{
    rigidbody.MovePosition(rigidbody.position + direction * Time.deltaTime * BallManager.Instance.initialBallSpeed);
}

private void OnCollisionEnter(Collision col)
{
    if (col.gameObject.CompareTag("Paddle"))
    {
        var cp = col.contacts[0];
        // and then you want to reflect on the normal of the contact..
        // a normalized position doesn't make any sense in this context
        direction = Vector2.Reflect(direction, cp.normal);
    }

或者如果你想根据球击中球拍的位置来增加方差,我会在球拍的每个尖端放一个对象,然后你可以

public static class Vector2Extensions
{
    public static float InverseLerp(thjs Vector2 value, Vector2 min, Vector2 max)
     {
         var direction = max - min;
         var AV = value - min;
         return Mathf.Clamp01(Vector2.Dot(AV, direction) / Vector2.Dot(direction, direction));
     }
}

检查你的打击接触是否更接近左(0)或右(1)尖端或正好在中心(0.5),并根据这个因素添加一些最小/最大Angular 偏移到向量.例如,使用plain reflect像以前一样,当正好在中心时,然后根据上面的偏移因素添加一些旋转,例如,使用

direction = Vector2.Reflect(direction, cp.normal);

// this will return a dynamic factor of whether the contact is closer to left (0), right (1) or in the middle (0.5) 
var inverseLerp = cp.point.InverseLerp(leftTip, rightTip);

// this will map the inverseLerp factor which goes between `0` and `1` 
// to the added angle offset which goes from -30° to 30°
var angle = Mathf.Lerp(-30, 30, inverseLerp);
direction = (Vector2)(Quaternion.Euler(0, 0, angle) * direction);

如果你愿意,你甚至可以完全删除Reflect,然后不添加旋转的方向,而是硬替换为一个新的方向基于相同的lerp之前

相关问题