将 child 添加到刚体使其移动

Adding child to rigidbody makes it move

我有一个 parent object 带有刚体(禁用重力)。使用脚本,我将带有框碰撞器的简单立方体添加为 children 到此 parent.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    public GameObject prefab;

    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            GameObject go = Instantiate(prefab, transform);
            go.transform.localPosition = new Vector3(10f, 10f, 10f);
        }
    }
}

这工作正常,但每次实例化和 parented 时,parent object 的轻微移动都是可见的。因此,最终在添加相当多的立方体之后,parent 甚至会从其原始位置移动整个单位,尽管速度始终是 Vector3.zero。

这种运动是如何发生的,我该如何预防?

所以,看来刚体的微小移动parent来自质心的变化。通过将 objects 移动或实例化为 childs,此值已更改,如 https://docs.unity3d.com/ScriptReference/Rigidbody-centerOfMass.html:

中所述

If you don't set the center of mass from a script it will be calculated automatically from all colliders attached to the rigidbody. After a custom center of mass set, it will no longer be recomputed automatically on modifications such as adding or removing colliders, translating them, scaling etc. To revert back to the automatically computed center of mass, use Rigidbody.ResetCenterOfMass.

最后,作为解决方案,我只是将局部质心设置为固定值。

rig.centerOfMass = Vector3.zero;

我对这个解决方案很满意,因为这也改变了旋转中心。我仍然不太确定为什么它会在质心变化时增加运动,因为我不明白为什么这会是现实行为。

rigidbody.position和transform.position也有区别。通过使用问题下评论的解决方案:

  • Unparent,再次移动child,parent
  • 禁用 child,移动 child,再次启用 child
  • 禁用 child 的碰撞器,移动 child,再次启用它

...可以保持 transform.position 不变,但 rigidbody.position 仍会发生变化。只要刚体处于睡眠状态,这两个值之间的差异就会持续存在。唤醒它,例如通过调用 Rigidbody.Wakeup() 将再次同步这两个值。由于两个值的不同,即使光线投射之类的事情也会失败,尽管光线可能击中了实际绘制网格的位置,而只是物理引擎认为它们在其他地方。再次醒来看起来也很难看,因为网格会弹回原位,它应该与刚体相匹配。