为什么transform.hasChanged始终为true?(即,谁负责将hasChanged设置为false?)

3
我并不完全理解Transform.hasChanged,所以我创建了一个简单的测试:
我创建了一个默认场景,创建了一个球,并在球上创建了一个脚本,在Update的每一帧中检查transform.hasChanged为什么它每一帧都返回TRUE? 顺便说一下:我假设Unity会在检测到变换时将值设置为TRUE,并在帧完成后重置为FALSE。但这似乎并没有发生。我到底缺少了什么?
using UnityEngine;
public class TestHasChanged : MonoBehaviour
{
    void Start() { }

    void Update()
    {
        if (transform.hasChanged) Debug.Log("Sphere hasChanged = TRUE!");
        else Debug.Log("Sphere hasChanged = FALSE!");
    }
}

接下来,我添加了一个监听器脚本,它仅仅是在每一帧更新时检查球体上的hasChanged。毫不意外,它在每一帧都返回true。最初的回答。
public class HasChangedListener : MonoBehaviour
{
    public GameObject target;   // the Sphere GO

    void Start() {}

    void Update()
    {
        if (target.transform.hasChanged) {
            Debug.Log("HasChangedListener::Update: hasChanged = TRUE!");
        } else {
            Debug.Log("HasChangedListener::Update: hasChanged = FALSE!");
        }
    }
}
2个回答

3
我认为这在文档中有说明,没有内置方法可以将hasChanged改回false,这是你的工作。好处是它很便宜(该位始终设置,没有分支),坏处是如果多个组件监视同一转换,则重置它的第一个组件会使第二个组件看到false。只要记住这一点,您就可以安全地在MonoBehaviour中“消耗”hasChanged。
我希望这能帮到你。

谢谢。我在文档中找不到任何解释这个的内容。正如你所提到的,如果你有多于一个监听器,那就有问题了(但是可以解决,只要你能够访问每个监听器,比如设置一个信号量)。唯一可能有意义的另一种情况是如果Unity确保实际游戏对象的Update方法最后执行。 - Rikk Carey

2
我相信我现在理解了Transform.hasChanged的工作原理和使用方式。
我的最初错误是认为Transform.hasChanged完全由Unity管理(即Unity自动:a)在每次改变Transform时设置hasTransform=true(duh)AND b)每帧末会重置为false 换句话说,您可以在任何Transform上调用hasChanged并期望它反映出本帧所做的更改。但这似乎是1/2错误(b)。
我现在相信Transform.hasTransform字段是一个未经管理的方便的“脏位”,需要由应用程序来管理。如预期,Unity将在对Transform进行更改时设置hasChanged=true。但是,仅此而已。您的工作(应用程序)是自己逐帧管理它(即在检查完后每帧设置hasChanged=false)。
如果我理解有误,请纠正我。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接