如何在脚本中编写逻辑检测Inspector窗口中对象字段的变更?
解决方案:检测Inspector中GameObject的位置变更
看起来你想要实现的是:当你在Inspector里手动修改Offset这个GameObject的位置时,自动触发GameObject_Changed()函数,让GameObject_NotChanged设为false,这样Update里就不会再用OffsetPosition覆盖它的位置了。你的现有代码逻辑没问题,但GameObject_Changed()没有被正确触发,这里给你两个可行的解决方案:
方案一:利用OnValidate()检测Inspector修改
Unity在Inspector中修改任何属性时,都会调用脚本的OnValidate()方法。我们可以在这里对比Offset的当前位置和OffsetPosition,判断是否是用户手动修改了GameObject的位置:
public GameObject Offset; public Vector3 OffsetPosition; public bool GameObject_NotChanged = true; void Update () { if(GameObject_NotChanged) { Offset.transform.position = OffsetPosition; } } void OnValidate() { // 先判断Offset是否为空,避免空引用报错 if (Offset == null) return; // 考虑浮点精度问题,用微小距离判断是否相等 if (Vector3.Distance(Offset.transform.position, OffsetPosition) > 0.001f) { // 位置不一致,说明用户手动修改了GameObject GameObject_Changed(); // 可选:把修改后的位置同步回OffsetPosition,保持两者一致 OffsetPosition = Offset.transform.position; } } void GameObject_Changed() { GameObject_NotChanged = false; }
优点:只在Inspector修改时触发,性能开销极低;缺点:无法检测运行时通过代码修改Offset位置的情况。
方案二:用Transform.hasChanged检测所有位置变更
Unity的Transform组件自带hasChanged属性,只要位置、旋转或缩放发生变化(不管是Inspector手动改还是代码改),这个属性就会变为true。我们可以在Update里检查这个属性:
public GameObject Offset; public Vector3 OffsetPosition; public bool GameObject_NotChanged = true; void Update () { if(GameObject_NotChanged) { Offset.transform.position = OffsetPosition; // 设置完位置后,重置hasChanged标记 Offset.transform.hasChanged = false; } else { // 可选:如果已经变更过,同步OffsetPosition到当前GameObject位置 OffsetPosition = Offset.transform.position; } // 检查Offset是否存在且位置发生了变更 if (Offset != null && Offset.transform.hasChanged) { GameObject_Changed(); // 重置标记,避免重复触发 Offset.transform.hasChanged = false; } } void GameObject_Changed() { GameObject_NotChanged = false; }
优点:能检测所有方式的Transform变更;缺点:需要每帧检查,性能开销略大(但对绝大多数场景可以忽略)。
注意事项
- 一定要判断
Offset是否为null,避免运行时空引用异常; - 用
Vector3.Distance而不是直接==对比,是因为浮点数值可能存在精度误差,直接相等判断容易出错。
内容的提问来源于stack exchange,提问作者Amar.linsila
相关产品推荐
相关产品推荐

