获取 GameObject 参考的最快方法是啥?

Posted

技术标签:

【中文标题】获取 GameObject 参考的最快方法是啥?【英文标题】:What is the fastest way to get GameObject reference?获取 GameObject 参考的最快方法是什么? 【发布时间】:2017-10-25 11:25:19 【问题描述】:

假设我的脚本定义如下。

public GameObject _GameObject;

private void Start()

[![enter image description here][1]][1]
    _GameObject = gameObject;


这会执行得更快吗?

public void SetActive(bool value)

  [1]: https://i.stack.imgur.com/S60FB.jpg
    gameObject.SetActive(value);

还是这个?

public void SetActive(bool value)

    _GameObject.SetActive(value);

【问题讨论】:

【参考方案1】:

在 Unity 4.x 及更低版本中,缓存方法会明显更快。在那些版本中,MonoBehaviour.transform 和 MonoBehaviour.gameObject 实际上不是字段;相反,“在引擎盖下”它们的行为就像带有附加访问器的属性。

因此访问 gameObject 属性将通过访问器对 Component.get_gameobject() 进行方法调用。当然,与简单的内存访问相比,方法调用自然会产生更多开销。 (Transform 更糟糕;显然访问器实际上调用了 GetComponent 方法来返回值!)

这就是为什么您经常会看到资深 Unity 开发人员缓存这些值的原因。

据我所知,Unity 5 已简化此流程以获得更好的性能;使用内置属性仍然会产生非常少量的开销,但据报道它是微不足道的。

来源:https://blogs.unity3d.com/2014/06/23/unity5-api-changes-automatic-script-updating/

【讨论】:

【参考方案2】:

我假设缓存变量比使用 Component 类中的 gameObject 变量更快,并且一个简单的测试证明了这一点。那是因为缓存它会给你引用而不是使用gameObject,它使用get 访问器来返回引用。不确定获取引用是否需要本机函数调用,但这是可能的。使用get 访问器比直接引用访问要慢。

假设您有 100 万个脚本调用 gameObject.activeSelf 或通过缓存版本 _GameObject.activeSelf

测试结果:

游戏对象:54ms

缓存的_GameObject:30ms

软件/硬件测试于:

Unity 5.6.0f3 Windows 10 专业版 MacBookPro11,4 16 GB 内存

重要吗?

在普通应用程序中,可能不是。在游戏中,是的。从游戏中删除 24ms 是一个很好的改进,具体取决于游戏的类型。

测试脚本:

public GameObject _GameObject;

void Start()

    Application.runInBackground = true;

    int iterations = 1000000;

    //TEST 1
    Stopwatch stopwatch1 = Stopwatch.StartNew();
    for (int i = 0; i < iterations; i++)
    
        bool active = gameObject.activeSelf;
    
    stopwatch1.Stop();

    //TEST 2
    Stopwatch stopwatch2 = Stopwatch.StartNew();
    for (int i = 0; i < iterations; i++)
    
        bool active = _GameObject.activeSelf;
    
    stopwatch2.Stop();
    //SHOW RESULT
    WriteLog(String.Format("gameObject: 0", stopwatch1.ElapsedMilliseconds));
    WriteLog(String.Format("Cached _GameObject: 0", stopwatch2.ElapsedMilliseconds));


void WriteLog(string log)

    UnityEngine.Debug.Log(log);

【讨论】:

以上是关于获取 GameObject 参考的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

获取时检查行存在的最快方法是啥?

获取数组第一项的最快方法是啥? [复制]

获取对象数据的浅拷贝的最快方法是啥?

获取媒体文件持续时间的最快方法是啥?

从 URL 获取域名/主机名的最快方法是啥?

如何在 hbase 表中获取计数记录?查询记录的最快方法是啥?