Unity 關于代碼(cpu)優(yōu)化的建議摘錄

1.對于不能使用事件觸發(fā)的代碼段,并不意味著每一幀都要去處理准脂。

void Update()

{

? ? ExampleExpensiveFunction();

}

可以通過以下代碼將這些邏輯每隔x?幀做一次處理。

void?Update()

{

????if(Time.frameCount % interval == 0)

? ? ? ? ExampleExpensiveFunction();

}

或者可以通過如下代碼將重量級的邏輯拆分到不同的幀去執(zhí)行

void?Update()

{

? ? if(Time.frameCount % interval ==0)

? ? ? ? ExampleExpensiveFunction1();

? ? else if(Time.frameCount % interval == 1)

? ? ? ? ExampleExpensiveFunction2();

}

2.盡量少使用的昂貴API

SendMessage()?BroadcastMessage() 內部使用了反射眼俊,使用事件或代理替代意狠。

Find() 需要Unity?遍歷所有內存中的GameObject粟关,建議不要使用疮胖。

Transform.rotation?Transform.position?設置Transform?的旋轉和世界坐標會觸發(fā)OnTransformChange?通知其所有的子孫Transform,因此相對來說比較昂貴尤其是那些有很多子孫的Transform闷板,應該盡量避免頻繁地賦值澎灸。

獲取位置信息時,優(yōu)先使用Transform.localPosition?而不是Transform.position遮晚,后者每次調用時都會重新計算物體的世界坐標性昭,而localPosition?則是一個緩存在Transform?中的變量,如果需要頻繁使用世界坐標县遣,那么建議緩存下來糜颠。

Update()?LateUpdate() 等生命期函數(shù)都有隱藏的消耗,所以即使是函數(shù)內部什么也不做也有消耗萧求,建議不要保留空的生命期函數(shù)其兴,尤其是Update() 這種每幀都會調用的生命期函數(shù)。

Vector?Vector?系列的magiture?方法和Distance?方法使用了平方根計算夸政,當僅僅需要比較兩個向量的長度的時候元旬,使用sqrMagnitude?效率更高。

Camera.main?不要使用守问,原因是內部調用了Find()?方法匀归。

3.利用是否在視椎體內的信息來優(yōu)化代碼。

private?Renderer myRenderer;

void Start()

{

? ? myRenderer = GetComponent<Renderer>();

}

void Update()

{

? ? UpdateTransformPosition();

? ? if(myRenderer.isVisible)

? ? {

? ? ? ? ExampleExpensiveFunction();

????}

}

4.可以使用LOD?技術提供的信息來優(yōu)化代碼

Unity?提供了CullingGroup?API?用來提供給開發(fā)者Culling?和LOD?相關的信息耗帕,使用這些信息可以實現(xiàn)類似meshrenderer?的基于距離來執(zhí)行不同效果的邏輯穆端。

5.關于垃圾回收相關的優(yōu)化建議

減少代碼產生垃圾的建議:

緩存:經(jīng)常重復調用的方法中如果有堆內存分配和回收邏輯,應該在特定時期將這些引用緩存下來仿便,避免每次調用都要分配對內存

void OnTriggerEnter(Collider other)

{

? ? Renderer[] allRenderers = FindObjectsOfType<Renderer>();

????ExampleFunction(allRenderers);

}

改為

private?Renderer[] allRenderers;

void Start()

{

? ? allRenderers = FindObjectsOfType<Renderer>();

}

void OnTriggerEnter(Collider other)

{

? ? ExampleFunction(allRenderers);

}

不要在頻繁調用的方法(Update)中分配堆內存

使用容器類時体啰,使用Clear()?方法代替生成新容器(或者使用容器池)

創(chuàng)建新的容器類實例時會觸發(fā)堆內存分配,可能會觸發(fā)垃圾回收

List myList = new List();

改為

myList.Clear();

使用對象池技術處理頻繁創(chuàng)建和銷毀的物體

不要頻繁操作(合并探越、截取等)string?類型的數(shù)據(jù)

string?是引用且不可變類型狡赐,每次操作string?類型后,都會重新創(chuàng)建新的string?類型钦幔,可能會觸發(fā)垃圾回收

創(chuàng)建string?時如果需要進行合并操作枕屉,可以使用StringBuilder?類用于輕量級地創(chuàng)建string。

移除所有不需要的Debug.Log?方法調用鲤氢,每個Debug.Log?都至少會創(chuàng)建和銷毀至少一個string搀擂。

需要顯示的string?數(shù)據(jù)西潘,如果需要合并操作,將string?數(shù)據(jù)拆分成不變的部分和變化的部分哨颂,以移除+?操作喷市。

public Text timerText;

void Update()

{

????timerText.text = "Time:" + DateTime.Now.ToString();

}

改為

public?Text headerText, timerText;

void Start()

{

? ? headerText.text = "Time";

}

void Update()

{

? ? timerText = DataTime.Now.ToString();

}

警惕那些返回數(shù)組、容器等的Unity?內置API威恼,因為每次調用他們都會返回一個新的引用品姓,可能引發(fā)垃圾回收,如需頻繁使用箫措,建議獲取一次后暫存下來腹备。

盡量減少裝箱和拆箱操作

創(chuàng)建協(xié)程會造成垃圾,因為Unity?需要為每個協(xié)程創(chuàng)建管理類實例斤蔓。

yield?return 0植酥;

會造成裝箱裝換,改為

yield return null;

可以避免裝箱引起的堆內存分配

while(!isComplete)

{

? ? yield return new WaitForSenconds(1f);

}

改為

WaitForSeconds delay = new WaitForSeconds(1f);

while(!isComplete)

{

? ? yield return delay;

}

可以減少垃圾產生弦牡。

匿名方法是引用類型會產生垃圾友驮,尤其是閉包會顯著增加內存使用和分配。

LINQ?和正則表達式會產生垃圾驾锰,因為其內部操作會昌盛裝箱操作卸留。

避免使用枚舉作為字典的key,因為會產生裝箱操作稻据,必須使用時寇窑,實現(xiàn)IEqualityComparer?接口并將其實例作為字典的比較器渡冻。

public?class MyEnumComparer : IEqualityComparer<MyEnum>

{

? ? public bool Equals(MyEnum x, MyEnum y)

????{

? ? ? ? return x==y;

????}

? ? public int GetHashCode(MyEnum x)

????{

? ? ? ? return (int)x;

????}

}

避免在結構體中添加引用類型字段(包括字符串類型),因為包含了引用類型的結構體需要被垃圾回收器完整檢測,對那些不是引用類型的變量也做了不必要的檢測栽惶⌒辣睿可以嘗試將引用類型拆分出來漫蛔。

減少不必要的引用緩存抛蚤,可以減少垃圾回收器檢索引用所用的時間。

在不會影響玩家體驗的時間點(如場景加載顯示Loading?界面時)調用System.GC.Collect()?來主動回收垃圾姓言。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末瞬项,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子何荚,更是在濱河造成了極大的恐慌囱淋,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件餐塘,死亡現(xiàn)場離奇詭異妥衣,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門税手,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜂筹,“玉大人,你說我怎么就攤上這事芦倒∫张玻” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵兵扬,是天一觀的道長麻裳。 經(jīng)常有香客問我,道長周霉,這世上最難降的妖魔是什么掂器? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮俱箱,結果婚禮上,老公的妹妹穿的比我還像新娘灭必。我一直安慰自己狞谱,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布禁漓。 她就那樣靜靜地躺著跟衅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪播歼。 梳的紋絲不亂的頭發(fā)上伶跷,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音秘狞,去河邊找鬼叭莫。 笑死,一個胖子當著我的面吹牛烁试,可吹牛的內容都是我干的雇初。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼减响,長吁一口氣:“原來是場噩夢啊……” “哼靖诗!你這毒婦竟也來了?” 一聲冷哼從身側響起支示,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤刊橘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后颂鸿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體促绵,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绞愚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叙甸。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖位衩,靈堂內的尸體忽然破棺而出裆蒸,到底是詐尸還是另有隱情,我是刑警寧澤糖驴,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布僚祷,位于F島的核電站,受9級特大地震影響贮缕,放射性物質發(fā)生泄漏辙谜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一感昼、第九天 我趴在偏房一處隱蔽的房頂上張望装哆。 院中可真熱鬧,春花似錦定嗓、人聲如沸蜕琴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凌简。三九已至,卻和暖如春恃逻,著一層夾襖步出監(jiān)牢的瞬間雏搂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工寇损, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凸郑,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓润绵,卻偏偏與公主長得像线椰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子尘盼,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內容

  • 最簡單的優(yōu)化建議: 1.PC平臺的話保持場景中顯示的頂點數(shù)少于200K~3M憨愉,移動設備的話少于10W,一切取決于你...
    好怕怕閱讀 5,888評論 1 12
  • 本文講解針對GC的優(yōu)化具體的操作卿捎,針對GC的產生以及原理不清晰的可以查看 unity3d性能:GC分析 文章配紫。本文...
    老掌門CEO閱讀 2,149評論 0 0
  • C#問題 1.在類的構造函數(shù)前加上static會報什么錯?為什么? 答:在構造函數(shù)如果有public修飾的靜態(tài)構造...
    元宇宙協(xié)會閱讀 9,026評論 4 17
  • 原文地址 http://www.fx114.net/qa-75-172454.aspx 使用Profiler工具...
    IongX閱讀 5,848評論 1 11
  • 表情是什么,我認為表情就是表現(xiàn)出來的情緒午阵。表情可以傳達很多信息躺孝。高興了當然就笑了享扔,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 124,908評論 2 7