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 多一個變量就多一個變量的字節數
儘量不要使用遞歸 容易棧溢出,處理慢