维持一个物体与另一个移动物体的相对位置时遇到问题

问题描述 投票:0回答:1

我在移动平台和让玩家跟随它们方面遇到问题。我希望玩家(在本例中为 linkedRbs[i])基本上“粘住”物体并在移动时保持其在物体上的相对位置 - 这在某种意义上是有效的,问题出现在设置 RigidBody 的位置时,相对位置反转(参考下图)。如果玩家相对位于对象的前面,则下一次物理更新它将移动到后面,然后移动到前面,反之亦然。我真的找不到一种方法来解决这个问题,并在没有向后向前运动的情况下将其保持在相同的相对位置 - 有帮助吗?这似乎是一个简单的错误,我已经掩盖了,但我已经尝试修复这个问题几个小时了。

图表示例

我用移动平台移动刚体,如下所示:

List<Rigidbody> linkedRbs = new List<Rigidbody>();
List<Vector3> linkedRbsRelativePos = new List<Vector3>();

private void FixedUpdate()
{
    for (int i = 0; i < linkedRbs.Count; i++) // "linkedRbs" are the rbs touching the moving object
    {
        if (GetRelativePos(linkedRbs[i]) != linkedRbsRelativePos[i]) // RB is not in the same place as it was the last physics update
        {
            Vector3 lastRBPos = linkedRbsRelativePos[i];
            linkedRbsRelativePos[i] = GetRelativePos(linkedRbs[i]);

            Vector3 worldRelativePos = transform.position - linkedRbsRelativePos[i];
            Vector3 newPos = lastRBPos + worldRelativePos;

            //Debug.Log($"Dir={worldRelativePos},lastPos={lastRBPos},newerPos={newer}");

            linkedRbs[i].MovePosition(new Vector3(newPos.x, linkedRbs[i].position.y, newPos.z));
        }
    }
}

private Vector3 GetRelativePos(Rigidbody rb)
{
    Vector3 playerRelative = rb.transform.InverseTransformPoint(transform.position);
    return playerRelative;
}

private void OnCollisionEnter(Collision collision)
{
    Collider collider = collision.collider;
    if(collider.TryGetComponent<PlayerColliderReference>(out PlayerColliderReference pcr))
    {
        Rigidbody _rb = pcr.GetComponentInParent<Rigidbody>();

        linkedRbs.Add(_rb);
        linkedRbsRelativePos.Add(GetRelativePos(_rb));
    }
}

private void OnCollisionExit(Collision collision)
{
    Collider collider = collision.collider;
    if (collider.TryGetComponent<PlayerColliderReference>(out PlayerColliderReference pcr))
    {
        Rigidbody _rb = pcr.GetComponentInParent<Rigidbody>();

        for (int i = 0; i < linkedRbs.Count; i++)
        {
            if (linkedRbs[i] == _rb)
            {
                linkedRbs.Remove(linkedRbs[i]);
                linkedRbsRelativePos.Remove(linkedRbsRelativePos[i]);
            }
        }
    }
}

简单地反转relativePos值显然会把我送到很远的地方,反转相对空间中的relativePos值也不能解决问题,因为每次物理更新时相对位置仍然会反转,只是相反。

c# unity-game-engine transform rigid-bodies
1个回答
0
投票

不确定我是否正确理解了你的问题,但如果你只是想让玩家与平台一起移动,那么你可以将平台位置更改为玩家(或 linkedRbs)位置的量。在这种情况下,您不需要搞乱奇怪的相对位置。这是一些应该有效的示例代码:

public List<Rigidbody> linkedRbs = new List<Rigidbody>();
Vector3 lastPosition;
private void Start()
{
    lastPosition = transform.position;
}
private void FixedUpdate()
{
    if (lastPosition != transform.position)
    {
        Vector3 changeInPosition = transform.position - lastPosition;
        changeInPosition.y = 0;
        for (int i = 0; i < linkedRbs.Count; i++)
        {
            linkedRbs[i].position += changeInPosition;
        }
        lastPosition = transform.position;
    }
} // plus all of your collision code 

在我的测试中,该代码做了我认为你的代码应该做的事情。

© www.soinside.com 2019 - 2024. All rights reserved.