c# - 缩放后未重新计算质心

标签 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();
  }
}

确实导致重心重新计算正确。然而,此时生成的对象似乎已经通过错误的 COM 进行了至少一次物理更新,因此已经获得了一些意想不到的动力。

为什么 COM 没有被自动重新计算,而我不必调用 ResetCenterOfMass()明确地?如果我必须手动触发它,我可以在调用 Instantiate() 后立即执行吗?和 Scale() ,而不是像这样推迟?

最佳答案

感谢@DMGregory GameDev如需建议,请调用 Physics.SyncTransforms在调用 Rigidbody.ResetCenterOfMass 之前解决了这个问题:

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 计算随后基于正确缩放的变换。

关于c# - 缩放后未重新计算质心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51377676/

相关文章:

c# 如何通过网页 (Safari) 在 iPAD 或 iPhone 上访问网络摄像头和麦克风

c# - 使用 Twitter API 获取 protected 推文

c# - 跟踪用户点数(如 SO)

c# - 找不到类型或命名空间名称 'MembershipUser'

unity3d - Gradle构建在Unity2018中失败

user-interface - Canvas 上的 Unity 粒子效果

c# - 切换字符串的部分

c# - 从脚本中清除编辑器控制台日志

android - 有没有人使用 OpenCV 实现了一个用于统一的 android 插件?

c# - 是否可以捕捉垂直于表面的预制件?