缩放后未重新计算质心

时间:2018-07-17 09:22:20

标签: c# unity3d

我在运行时生成了一个预制对象(实际上是在另一个对象的Start()方法中),并且需要对对象进行缩放。我制作了一个小组件来处理此问题:

public class Spawner : MonoBehaviour {

  public Transform SpawnPrefab;
  public Vector3 Scale;

    void Start () {
      var spawn = Instantiate(SpawnPrefab, Vector3.zero, Quaternion.identity);
      spawn.localScale = Vector3.Scale(spawn.localScale, Scale);
      // spawn.GetComponent<Rigidbody>().ResetCenterOfMass();  // Has no effect
    }
}

我生成的预制件的枢轴点与对象的质心不一致。因此,重新缩放意味着相对于枢轴的重心位置将发生变化。但是,不是会自动更新,因此生成的对象具有意外的物理特性。

我尝试在调用GetComponent<Rigidbody>().ResetCenterOfMass()之后立即添加对Scale()的调用(上面的注释行),但这没有效果。

但是,如果我在添加到衍生对象的单独小组件的ResetCenterOfMass()方法的Start()方法中调用public class COMReset : MonoBehaviour { void Start() { GetComponent<Rigidbody>().ResetCenterOfMass(); } } ,例如

ResetCenterOfMass()

这样做 会导致重新正确计算质心。但是,此时生成的对象似乎已经通过至少一次错误的COM进行了物理更新,因此已经获得了一些意外的动力。

为什么在不必显式调用Instantiate()的情况下不能自动重新计算COM?而且,如果我必须手动触发它,是否可以在调用Scale()Cypress.Commands.add( 'expectLdapUsersListToBe', (listUserNames, listUserIds) => { const ldapUserNames = cy.get(ADD_LDAP_USER_DOM.texts.ldapUserNames); ldapUserNames.should('have.length', listUserNames.length); ldapUserNames.each(($item, index) => { cy.wrap($item).contains(listUserNames[index]); }); const ldapUserIds = cy.get(ADD_LDAP_USER_DOM.texts.ldapUserIds); ldapUserIds.should('have.length', listUserIds.length); ldapUserIds.each(($item, index) => { cy.wrap($item).contains(listUserIds[index]); }); } ); 之后立即执行此操作,而不是像这样推迟执行?

1 个答案:

答案 0 :(得分:1)

感谢GameDev上的@DMGregory的建议,在调用Rigidbody.ResetCenterOfMass之前调用Physics.SyncTransforms可以解决此问题:

public class Spawner : MonoBehaviour {

  public Transform SpawnPrefab;
  public Vector3 Scale;

    void Start () {
      var spawn = Instantiate(SpawnPrefab, Vector3.zero, Quaternion.identity);
      spawn.localScale = Vector3.Scale(spawn.localScale, Scale);
      Physics.SyncTransforms();
      spawn.GetComponent<Rigidbody>().ResetCenterOfMass();
    }
}

显然,转换比例的这种直接修改不会自动传递到物理引擎,但是Physics.SyncTransforms让我们手动将这些更改向下冲刷到PhysX,这样ResetCenterOfMass计算就可以了基于正确缩放的变换。