答案 0 :(得分:1)
在Unity 4.x及更低版本中,缓存方法会明显加快。在这些版本中,MonoBehaviour.transform和MonoBehaviour.gameObject实际上不是字段;相反,“引擎盖下”它们表现得像附加存取器的属性。
因此,访问gameObject属性将通过访问器对Component.get_gameobject()进行方法调用。当然,方法调用自然会比简单的内存访问带来更多的开销。 (变换更糟糕;显然访问者实际上调用了GetComponent方法来返回值!)
这就是为什么你经常会看到经验丰富的Unity开发人员缓存这些值。
我有充分的权威,在Unity 5中简化了这个过程以获得更好的性能;使用内置属性仍然会产生非常小的开销,但据报道它是无关紧要的。
来源:https://blogs.unity3d.com/2014/06/23/unity5-api-changes-automatic-script-updating/
答案 1 :(得分:1)
我认为缓存变量比使用Component
类中的gameObject
变量更快,并且一个简单的测试证明是真的。这是因为缓存它会为您提供参考,而不是使用gameObject
使用get
访问器来返回引用。不确定获取引用是否需要本机函数调用,但这是可能的。使用get
访问者比直接引用访问速度慢。
假设您有100万个脚本调用gameObject.activeSelf
或通过缓存版本_GameObject.activeSelf
。
测试结果:
gameObject:
54
ms缓存_GameObject:
30
ms
软件/硬件测试:
重要吗?
在普通应用中,也许不是。在游戏中,是的。从游戏中删除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);
}