十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
今天小編給大家分享一下Unity代碼層優(yōu)化和規(guī)避的方法有哪些的相關(guān)知識點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
目前創(chuàng)新互聯(lián)建站已為上1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機(jī)、網(wǎng)站托管、服務(wù)器租用、企業(yè)網(wǎng)站設(shè)計、靈臺網(wǎng)站維護(hù)等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
1.盡可能少用不用循環(huán)邏輯精簡循環(huán)主體代碼(While,for,foreach,遞歸)
在業(yè)務(wù)需求層面能避免循環(huán)邏輯的時候盡量避免,確實(shí)是需要循環(huán)邏輯的話就把邏輯理清楚,主要循環(huán)體的代碼不能有任何多余的變量或者多余內(nèi)存占用。另外:
for(int i=0;i2.巧用生命周期函數(shù)Update和LateUpdata。
明確每一幀Updata和固定幀LateUpdata的函數(shù)意義,在使用兩者的時候要明確當(dāng)前需求是否要高頻率的執(zhí)行調(diào)用,如果確實(shí)需要每一幀都執(zhí)行調(diào)用或者在單幀上進(jìn)行邏輯處理(比如畫面渲染等)那我們就用到Updata;另外如果我們對刷新執(zhí)行的頻率要求不高(比如物理的位移旋轉(zhuǎn)等邏輯)我們就可以用到LateUpdata;刪除空的Update方法
void Update() { if (isTrue) { isTrue = false;}//一定要加條件保護(hù) } private void LateUpdate() { transform.Rotate(Vector3.up * Time.fixedDeltaTime * speed); }3.只在變化發(fā)生時才去執(zhí)行代碼(UI界面數(shù)據(jù)刷新)。
很多時候的邏輯我們都是不用特殊處理時時關(guān)照的,比如UI界面的數(shù)據(jù)刷新,很多初學(xué)者喜歡把ui的刷新邏輯直接扔在Updata里面,這樣雖然很省事我們不必再單獨(dú)的對界面數(shù)據(jù)的管理和維護(hù),但是界面如果數(shù)據(jù)量大,更新頻繁這時候?qū)Τ绦蚓驮斐珊艽蟮匿秩矩?fù)擔(dān),我們可以通過使用委托等方法只有在有數(shù)據(jù)更新的時候調(diào)用ui的界面刷新邏輯
public delegate void MyDelegate(int score);//定義委托 public MyDelegate myDelegate; //聲明委托 private int score = 0; public int Score { get => score; set { score = value; myDelegate?.Invoke(score); } } private void Start() { myDelegate += UpdataUIData;//委托注冊事件 } public void UpdataUIData(int score) { //刷新ui界面數(shù)據(jù) }4.將需要頻繁執(zhí)行且不能通過事件觸發(fā)的方法改為每隔幾幀執(zhí)行一次。比如剛才說的lateUpdata固定幀。除去這個外我們還可以靈活運(yùn)用協(xié)同,在一開始的時候就開啟一個協(xié)同
private void Start() { InvokeRepeating("RunSomeThing",1,5);//一秒鐘執(zhí)行五次 } private int interval = 3;//間隔幀 void Update() { if (Time.frameCount % interval == 0)//每三幀執(zhí)行一次 { RunSomeThing(); } } public void RunSomeThing() { }5.使用緩存存儲需要反復(fù)獲取和使用的值。
.動態(tài)獲取的組件可以存儲到全局變量中,使用的時候直接取避免了反復(fù)獲取
.反復(fù)使用的臨時變量,聲明的時候我們就可以放到全局存儲起來
.動態(tài)實(shí)例化出來的對象,我們要想辦法給管理起來方便下次直接使用6.數(shù)值類型盡量避免使用float,而使用int,特別是在手機(jī)游戲中,盡量少用復(fù)雜的數(shù)學(xué)函數(shù),比如sin,cos等函數(shù)。改除法/為乘法,例如:使用x*0.5f而不是 x/2.0f 。
7.主動進(jìn)行垃圾回收
void Update() { //固定時間GC回收但也不能太頻繁,建議跳轉(zhuǎn)場景的時候或者重要模塊切換的時候回收 if (Time.frameCount % 50 == 0) { GC.Collect(); } }二:避免調(diào)用高開銷的Unity API
1. SendMessage()和BroadcastMessage()使用了反射而反射會造成更多的CPU開銷。你可以直接調(diào)用或通過C#的委托來實(shí)現(xiàn)。
2. Find()方法會遍歷內(nèi)存中的每個GameObject和組件,隨著項(xiàng)目規(guī)模的擴(kuò)張,它的開銷將會越來越大。避免使用Find()和與其類似的方法,盡可能不要再Update或FixedUpdate中使用搜索方法
3.Transform中設(shè)置position和rotation會觸發(fā)內(nèi)部的OnTransformChanged事件并傳播到所有的子級對象中,對于含有非常對子物體的對象來說,這種操作開銷很大,應(yīng)該 減少對position和rotation的修改。如果某個方法中要分別設(shè)置position的xyz,可以創(chuàng)建一個Vector3然后分別將xyz設(shè)置到該Vector3中,最后將Vector3設(shè)置給position,而不要每次分開設(shè)置position的xyz。嘗試使用localPosition替代position。localPosition存儲在transform中,訪問該值時,Unity會直接將其返回,而position在每次訪問時都會重新計算,如果要經(jīng)常獲取position,可以將其緩存起來。
4.Update()和LateUpdate()等事件方法的每次調(diào)用都需要引擎代碼與托管代碼之間進(jìn)行通信,還要Unity進(jìn)行安全檢查(GameObject狀態(tài)是否合法等),即使這些事件方法的方法體是空的,引擎任然會對其進(jìn)行調(diào)用。因此,為避免浪費(fèi)CPU時間,應(yīng)該 刪除空的事件方法。另外,如果某個活動狀態(tài)(gameObject.active == true)的GameObject上的腳本中含有Awake()方法,即使這個腳本沒有被啟用(enabled==false),Awake()方法也會執(zhí)行。如果游戲中含有非常多的帶有Update()方法的MonoBehavior,應(yīng)該嘗試改變代碼結(jié)構(gòu)來減少開銷,這有一篇相關(guān)的博客。
5.Vector2和Vector3()向量的數(shù)學(xué)運(yùn)算要比普通的浮點(diǎn)數(shù)和整數(shù)的數(shù)學(xué)運(yùn)算更加復(fù)雜,訪問向量的某些屬性可能會帶來隱含的開銷,例如magnitude屬性(不僅針對向量,例如上文提到的Transform.position)。每次訪問magnitude,引擎都會進(jìn)行開平方運(yùn)算,雖然單次計算并不會消耗多少時間, 但當(dāng)數(shù)量級足夠大時,這種開銷將變得明顯??梢試L試使用sqrMagnitude(即magnitude的平方)替代magnitude,減少開平方操作。
6.Camera.main所引起的問題與Find()方法類似,應(yīng)該避免使用Camera.main并且手動管理對相機(jī)的引用。
以上就是“Unity代碼層優(yōu)化和規(guī)避的方法有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
當(dāng)前題目:Unity代碼層優(yōu)化和規(guī)避的方法有哪些
文章來源:http://m.jiaotiyi.com/article/gdheig.html