Unity3D 为什么保存Transform等引用效率会更高

正常来说,大部分同学一般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):

  1. // Putting transform into variable
  2.     private Transform myTransform;
  3.    
  4.     // This is called before anything else in script is called
  5.     void Awake() {
  6.         // Caching transform
  7.         myTransform = transform;
  8.     }

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):

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class EnemyAI : MonoBehaviour {
  5.     public Transform target;
  6.     public int moveSpeed;
  7.     public int rotationSpeed;
  8.    
  9.     // Putting transform into variable
  10.     private Transform myTransform;
  11.    
  12.     // This is called before anything else in script is called
  13.     void Awake() {
  14.         // Caching transform
  15.         myTransform = transform;
  16.     }
  17.  
  18.     // Use this for initialization
  19.     void Start () {
  20.         GameObject go = GameObject.FindGameObjectWithTag("Player");
  21.        
  22.         target = go.transform;
  23.     }
  24.    
  25.     // Update is called once per frame
  26.     void Update () {
  27.         Debug.DrawLine(target.position, myTransform.positionColor.yellow);   
  28.        
  29.         // Look at target (player)
  30.         myTransform.rotation = Quaternion.Slerp
  31.     }
  32. }
时间: 2024-11-14 16:39:11

Unity3D 为什么保存Transform等引用效率会更高的相关文章

【酷熊科技】工作积累 ----------- Unity3D / c 语言 使用 Stringbuilder 引用头文件 using System.Text

使用 StringBuilder Unity3D / c 语言 使用 Stringbuilder 引用头文件 using System.Text 简述StringBuilder和String的区别? String是字符串常量.  StringBuffer是字符串变量 ,线程安全. StringBuilder是字符串变量,线程不安全.  String类型是个不可变的对象,当每次对String进行改变时都需要生成一个新的String对象,然后将指针指向一个新的对象,如果在一个循环里面,不断的改变一个

unity3d 自动保存

using UnityEngine; using UnityEditor; using System; public class AutoSave : EditorWindow { private bool autoSaveScene = true; private bool showMessage = true; private bool isStarted = false; private int intervalScene; private DateTime lastSaveTimeSce

Effective JavaScript Item 24 使用一个变量来保存arguments的引用

本系列作为Effective JavaScript的读书笔记. 假设需要一个API用来遍历若干元素,像下面这样: var it = values(1, 4, 1, 4, 2, 1, 3, 5, 6); it.next(); // 1 it.next(); // 4 it.next(); // 1 相应的实现可以是: function values() { var i = 0, n = arguments.length; return { hasNext: function() { return

C# 文件选择对话框,Unity3d文件保存对话框

using OpenWinForm = System.Windows.Forms; 在unity3d中,使用FileDialog应该把System.Windows.Forms.dll拷贝到unity工程的plugins目录, 并且把Player Setting中Other Settings下的api compatibility Level改为.NET2.0.要不无法编译通过. //比如unity3d要让用户选择某一个音乐文件播放; private void SelectMusic(){     

《转》Unity3D研究院之UGUI一个优化效率小技巧

无意间发现了一个小技巧.如下图所示,可以发现UGUI的Image组件的RaycastTarget勾选以后会消耗一些效率,为了节省效率就不要勾选它了,不仅Image组件Text组件也有这样的问题. 一般UI里也就是按钮才需要接收响应事件,那么大部分image和text是是不需要开RaycastTarget的. 但是问题就来了,Unity默认在hierarchy窗口Create->UI->Image .Text的时候就会自动帮我们勾选上RaycastTarget, 一个复杂点的界面至少也300+个

C++内存检测(定位到确定地址,并且用hash表来保存提高了搜索效率)

#include <iostream> #include <malloc.h> #include <string.h> #include <stdio.h> #define DefaultSize 7 using namespace std; struct Node { char *pname;//文件名字 int line;//行号 int size;//大小 long long save;//存储地址ip Node *next; }; struct Ha

Unity3D 摄像机的Transform通过摇杆输出的方向

要解决的问题是:摄像机的方向不固定,当摇杆向前(0,1)推时,主角要往摄像机的朝向(忽略Y方向)走,当摇杆往右(1,0)推的时,主角朝摄像机的右方向 /// <summary> /// 摄像机的Transform通过摇杆输出的方向 /// </summary> /// <param name="t">摄像机的transform</param> /// <param name="dir">摇杆的方向</

高效effective C++ 55条款之个人学习笔记二

条款11:在operator=里面处理自我赋值 该条款确保对象自我赋值的时候operator=有很好的行为,必须对对象进行判断,比较.注意Copy and swap技术, 还有注意当函数操作多个对象的时候,也能对其进行判断. 条款12: 复制对象的时候勿忘其每一个成分 对于对象的复制我们必须要保证其完整性,那么关键地方就在于copy构造和=赋值操作的时候,必须做到每个数据 成员全部复制到新的对象.特别注意当继承子类复制的时候,必须将父类每个成员考虑到,两种方式考虑,一种 记得加上初始化父类成员列

Unity3D占用内存太大的解决方法

原文链接:http://www.cnblogs.com/88999660/archive/2013/03/15/2961663.html 最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. 这里写下关于Unity3D对于内存的管理与优化. Unity3D 里有两种动态加载机制:一个是Resources.Load,另外一个通过AssetBundle,其实两者区别不大. Resources.Load就是从一个缺省打进程序包里的AssetBundle里加载资源,而一般AssetBund