Unity3d优化
1.不要使用万金油的方法SendMessage
2.Animator.Initialize会在GameObject.Activate里调用,非常耗时
3.不要在Update使用GetComponent
4.不要在Update使用StartCoroutine
5.不要直接访问gameobject的tag属性。
比如if (go.tag == “human”)最好换成if (go.CompareTag (“human”))。因为访问物体的tag属性会在堆上额外的分配空间。如果在循环中这么处理,留下的垃圾就可想而知了。
6. 不要使用foreach
在finally里,mono编译出来的代码中有一次将valuetype的Enumerator,boxing的过程!!
What a waste!!!
这就是Unity中所带的老版本mono编译器的一个bug!**
使用
Dictionary<string, BuffCDTime>.Enumerator e = buffCDDatas.GetEnumerator(); while(e.MoveNext()) { KeyValuePair<string, BuffCDTime> v = e.Current; }
7.不要在Update里面,使用AddComponent方法,也不能在Update时里面使用Destroy方法
不要在Update函数使用iTween
8.ToString也会GC alloc(这个要进一步验证,时有时无)
9.之前在另一个地方看见过2014Unity亚洲开发者大会会议简录上有一个说法:
检测每帧都具有20B以上内存分配的选项
10.下面的代码是几个gc“噩梦”
String的相加操作,会频繁申请内存并释放,导致gc频繁,使用System.Text.StringBuilder代替
function ConcatExample(intArray: int[]) { var line = intArray[0].ToString(); for (i = 1; i < intArray.Length; i++) { line += ", " + intArray[i].ToString(); } return line; }
11.在函数中动态new array,最好将一个array、传进函数里修改
function RandomList(numElements: int) { var result = new float[numElements]; for (i = 0; i < numElements; i++) { result[i] = Random.value; } return result; } public void CheckRespawn(float nowTime,ref List<GameObject> autoRespawns) { for (int i = 0; i < autoItems.Count; i++) { if (nowTime - autoItems[i].lastUse >= autoItems[i].time) { autoRespawns.Add(autoItems[i].obj); } } }
NGUI UIAtlas中存在这们调用问题
public BetterList<string> GetListOfSprites() { if (mReplacement != null) return mReplacement.GetListOfSprites(); if (mSprites.Count == 0) Upgrade(); BetterList<string> list = new BetterList<string>(); for (int i = 0, imax = mSprites.Count; i < imax; ++i) { UISpriteData s = mSprites[i]; if (s != null && !string.IsNullOrEmpty(s.name)) list.Add(s.name); } return list; }
12.不要使用OnGUI()
void OnGUI() { GUI.skin.label.fontSize = 20; if (fpsCount > 20) { GUI.color = new Color(0, 1.0f, 0); } else { UI.color = new Color(1.0f, 0, 0); } GUI.Label(new Rect(2,Screen.height-30,800,100),text); }
13.优化GetComponent
使用 Component mono = GameObjectUtility.Get(ongo, typeof(GunpowderSingle))
替换 ongo.GetComponent<GunpowderSingle>()
GameObjectUtility.DestroyGameObject()
替换 GameObject.Destroy()
14.使用ObjectPool缓存通用Object
15.使用PoolManager缓存GameObject
16.其他
GameObject.FindGameObjectsWithTag 每次调用40B GC Alloc
Physics.SphereCastAll 每次调用40B GC Alloc
List<枚举> .contains会有GC
不要使用参数列表void Test(params int[] array) 调用该函数(传入空参)就会产生40B的GC 多一个变量就多一个变量的字节数
尽量不要使用递归 容易栈溢出,处理慢