Unity,如果transform.position刚刚改变,Rigidbody.MovePosition()将不起作用

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

问题

这段代码有效。 ↓

private void FixedUpdate()
{
    Vector3 newPosition = new Vector3(0, 1, 0);
    GetComponent<Rigidbody>().MovePosition(newPosition);
}

此代码不起作用。 ↓

private void FixedUpdate()
{
    Vector3 newPosition = new Vector3(0, 1, 0);

    Vector3 oldPosition = transform.position;
    transform.position = newPosition;
    transform.position = oldPosition;

    GetComponent<Rigidbody>().MovePosition(newPosition);
}

我在Unity 2019.4和2020.3中进行了测试。

所以,如果transform.position刚刚改变,Rigidbody.MovePosition()似乎将不起作用。
为什么会出现这种情况?

添加于2021.9.3

我发现我可以使用Physics2D.SyncTransforms()来解决这个问题。
物理.SyncTransforms

这段代码有效。 ↓

private void FixedUpdate()
{
    Vector3 newPosition = new Vector3(0, 1, 0);

    Vector3 oldPosition = transform.position;
    transform.position = newPosition;
    transform.position = oldPosition;

    Physics2D.SyncTransforms();  //newly added

    GetComponent<Rigidbody>().MovePosition(newPosition);
}
c# unity-game-engine game-physics
2个回答
1
投票

首先,只有当您不断检查碰撞/触发时,才应使用 Rigidbody 的 MovePosition 方法,无论附加到游戏对象的刚体是否具有连续/离散碰撞检测。如果您确实在项目中没有使用太多物理,请避免使用它并使用其变换来移动对象。

对象不移动的原因(至少我假设这是您在屏幕上看到的)是您尝试将对象的变换位置和刚体设置为相同的 FixedUpdate 时间戳并更新 FixUpdate 上的变换是与现有的最佳实践相去甚远。如果您将编辑变换位置的行移动到 Update 方法,它会可能 移动对象(取决于游戏运行的固定更新的帧速率和时间戳)。

我的建议是,要么停止在FixedUpdate上更新变换的位置并仅使用rb.MovePosition方法,要么删除FixedUpdate方法并在Update()方法上更新变换的位置。

另外,请确保暂时不要更改 MonoBehaviour 类中其他任何位置的transform.position、rb.position 或 rb.velocity,只是为了确保这段代码正常工作。


1
投票

Physics2D.SyncTransforms();这个功能对我有用... 我需要使用游戏对象的 Transform.Translate,然后使用 Rigibody.MovePosition 作为子游戏对象。孩子如何收到父母的翻译, rb.MovePosition 不起作用......两个函数之间的物理更新就足够了。 Physics2D.SyncTransforms() 允许更新transform.translation的物理。

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