c# - 如何将物体从碰撞点移动到物体末端 |统一

标签 c# unity-game-engine 2d

我是 Unity 新手,在解决问题时遇到了一些麻烦。 我有一个 Sprite ,它只是一个带有 boxCollider2d 的普通正方形。假设有一个球在其上碰撞,我希望该球从碰撞点平稳地移动到方形 Sprite 的末端。我已经写了一些代码,但它似乎不起作用。下面的脚本是在球落下的方形 Sprite 上的。

public class HandleRollerMovement : MonoBehaviour
{
 private float desiredDuration = 1f;
 private float elapsedTime = 0f;
 private Vector3 endPosition;
 private Vector3 startPosition;
 private Rigidbody2D eggRigidBody;
 private BoxCollider2D boxCollider2D;
 private float rollerLegth;

 private void Start()
{
    boxCollider2D = GetComponent<BoxCollider2D>();
    rollerLegth = boxCollider2D.bounds.size.x;
}

private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Egg"))
    {
        eggRigidBody = collision.gameObject.GetComponent<Rigidbody2D>();
        if (eggRigidBody != null)
        {
            startPosition = eggRigidBody.transform.position;
            Vector2 contactPoint = GetPointOfContact(collision);
            float ToMove = Mathf.Abs(rollerLegth - Mathf.Abs(contactPoint.x));

            endPosition = new Vector3(startPosition.x + ToMove, eggRigidBody.transform.position.y, 0);
            StartCoroutine(MoveEgg());
        }
    }
}

private IEnumerator MoveEgg()
{
    while (elapsedTime < desiredDuration)
    {
        eggRigidBody.transform.position = Vector3.Lerp(startPosition, endPosition, (elapsedTime / desiredDuration));
        elapsedTime += Time.deltaTime;
        yield return null;
    }
    yield return null;
}
Vector2 GetPointOfContact(Collision2D collision)
{
    ContactPoint2D contactPoint = collision.contacts[0];
    Vector2 contactPosition = contactPoint.point;
    return contactPosition;
 }
}

最佳答案

我认为问题在于

float ToMove = Mathf.Abs(rollerLegth - Mathf.Abs(contactPoint.x));

您正在使用绝对世界空间位置contactPoint.x并从普通大小值中减去它。

相反,我可能宁愿比较两个边界并做类似的事情

var eggRigidBody = collision.rigidbody;

if(!eggRigidBody) return;

var startPosition = (Vector2)eggRigidBody.position;
var endPosition = startPosition;

// basically takes the right edge of this collider and adds the distance between the balls left edge and pivot position
endPosition.x = boxCollider2D.bounds.max.x + (startPosition.x - collision.collider.bounds.min.x);

// you might even need to add some additional buffer so the ball isn't stuck on the right edge
//endPosition.x += 0.1f;

StartCoroutine(MoveEgg(eggRigidBody, startPosition, endPosition, (endPosition.x - startPosition.x) / rollerLegth * desiredDuration);
    
    

然后相应地将它们作为参数传递

private IEnumerator MoveEgg(Rigidbody2D rb, Vector2 startPosition, Vector2 endPosition, float duration)
{
    for(var elapsedTime = 0f; elapsedTime < duration; elapsedTime += Time.deltaTime;)
    {
        rb.MovePosition(Vector2.Lerp(startPosition, endPosition, elapsedTime / duration));
        yield return null;
    }
    
    rb.MovePosition(endPosition);
}

关于c# - 如何将物体从碰撞点移动到物体末端 |统一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76854712/

相关文章:

matrix - Unity3D 相机矩阵的高级信息

algorithm - 连续物理引擎的碰撞检测技术

C# DLL 的包装器

c# - 如何知道为类型定义的属性?

javascript - 使用动态创建的内容将参数传递给 JS 函数

c# - 如何卸载附加场景?

c# Grpc Client 无法连接到 localhost 上 docker(for windows) 容器中托管的 Grpc Server

android - Unity 使用什么默认 keystore 进行 apk 签名?

c - 在 C 中使用另一个数组初始化数组大小

python - sge-pygame 旋转父子 Sprite