c# - 如果刚刚更改了 transform.position,Unity,Rigidbody.MovePosition() 将不起作用
问题描述
问题
此代码有效。↓</p>
private void FixedUpdate()
{
Vector3 newPosition = new Vector3(0, 1, 0);
GetComponent<Rigidbody>().MovePosition(newPosition);
}
此代码不起作用。↓</p>
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() 相关。
Physics.autoSyncTransforms , Physics.SyncTransforms
此代码有效。↓</p>
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);
}
另一个小问题
另一个小问题以及我在上面编写代码的原因。
我在我的项目中没有使用太多物理。我通过设置 transform.position 改变了位置。
我学习了一些物理学,并认为 Kinematic 和 Rigidbody2D.MovePosition() 适合我。
旧代码大约有几百行。用 Rigidbody2D.MovePosition() 替换 transform.position 需要一些时间。
所以我想我可以做以下事情来节省时间:
(1)保存初始位置,
(2)使用旧代码改变位置(transform.position),
(3)保存新位置,
(4)恢复旧位置,
(5)最后使用Rigidbody2D.MovePosition(newPosition)改变位置。
但事实证明我不能在 Unity 中做到这一点。
有什么好主意吗?
解决方案
首先,Rigidbody 的 MovePosition 方法只有在你不断检查碰撞/触发时才应该使用,无论附着到游戏对象的刚体是否具有连续/离散碰撞检测。如果您确实在项目中没有使用太多物理,请避免使用它并使用其变换来移动对象。
对象没有移动的原因(至少我假设这是您在屏幕上看到的)是您试图将对象的变换位置和刚体设置为相同的FixedUpdate时间戳,并且在 FixedUpdate 上更新变换很远来自任何最佳实践。如果将编辑变换位置的行移动到Update方法,它可能会移动对象(取决于游戏运行的 FixedUpdate 的帧速率和时间戳)。
我的建议是,要么停止在 FixedUpdate 上更新变换的位置,只使用 rb.MovePosition 方法,要么删除 FixedUpdate 方法并在 Update() 方法上更新变换的位置。
另外,请确保您暂时不要更改 MonoBehaviour 类中其他任何地方的 transform.position、rb.position 或 rb.velocity,以确保这段代码可以正常工作。
推荐阅读
- r - 识别向量中的 NA 集
- python - 为什么pickle加载numpy数组比numpy快得多?
- r - R中的对象何时修改到位?
- javascript - 如何使用Angular6在基于动态计算器的结果输入字段中绑定动态公式结果?
- javascript - 关于 JavaScript 中函数格式的问题
- marklogic - MarkLogic - 使用 Javascript 将变量传递给 XML
- java - 在 Gradle 任务中拉取和运行依赖项
- python - 使用 zip 值作为索引切片多索引数据帧
- perl - Perl:异步执行 10 个系统进程
- excel - 使用 AVERAGEIF 计算一段时间内的时间表有效性,意外结果