正常来说,大部分同学一般get transform都直接gameobject.transform使用。但往往,你会发现有些人会将transform引用保存起来,例如:
private Transform myTransform;
void Awake() {
myTransform = transform;
}
然后使用myTransform替代this.transform。如果你不知道u3d内部实现获取方式你肯定会以为这人脑抽水了,有直接的不用,还自己保存起来。
this.transform并不是变量,而是一个get/set属性(property)。
using System;
using System.Runtime.CompilerServices;
using UnityEngineInternal;
namespace UnityEngine
{
public class Component : Object
{
public extern Transform transform
{
[WrapperlessIcall]
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}
}
}
调用this.transform实际上是一个调用intenal method的过程(这是用C/C++写的,不是MONO的)。值得注意的是这个调用方法略慢,因为你需要调用外部的CIL(aka interop),花费了额外的性能。
估计大概的效率(没测试,以后有时间再弄,大家可以参考下文章最后的链接):
GetComponent是this.transform的10倍消耗时间。
this.transform是保存了引用myTransform的1.5倍的消耗时间。(因为新版优化了不少)
实际上:
如果你是偶尔调用一下transform的话,那就不要保留它的引用了,直接this.transform。
如果是Update中,每一帧都要改变的话,还是保留一下this.transform的引用吧。毕竟倘若一大堆东西的话,能快不少呢。
原文如下:
I have a question from this Burgzerg tutorial http://www.youtube.com/watch?v=O8-oZfi4utY
I don‘t understand why Pete says to cache the transform by defining the myTransform variable at the top of the script and then assigning it a transform value in the Awake() function like as follows:
Code (csharp):
- // Putting transform into variable
- private Transform myTransform;
- // This is called before anything else in script is called
- void Awake() {
- // Caching transform
- myTransform = transform;
- }
I understand that Awake() is called before anything else in the entire script but how does that help cache the transform of the object that this script is attached to? Why not just use Update() to constantly make calls to the object‘s transform? After all, the transform is most likely going to be constantly changing.
The full code from the video is below:
Code (csharp):
- using UnityEngine;
- using System.Collections;
- public class EnemyAI : MonoBehaviour {
- public Transform target;
- public int moveSpeed;
- public int rotationSpeed;
- // Putting transform into variable
- private Transform myTransform;
- // This is called before anything else in script is called
- void Awake() {
- // Caching transform
- myTransform = transform;
- }
- // Use this for initialization
- void Start () {
- GameObject go = GameObject.FindGameObjectWithTag("Player");
- target = go.transform;
- }
- // Update is called once per frame
- void Update () {
- Debug.DrawLine(target.position, myTransform.position, Color.yellow);
- // Look at target (player)
- myTransform.rotation = Quaternion.Slerp
- }
- }