要登陸Quest Store,你的應(yīng)用需要保持每秒72幀的穩(wěn)定速度。這并不容易實(shí)現(xiàn),但通過遵循相關(guān)文檔和最佳實(shí)踐來優(yōu)化性能,你應(yīng)該依然可以提交一款符合標(biāo)準(zhǔn)的作品。然而,現(xiàn)在的游戲越來越大,同時(shí)將所有一切都保存在內(nèi)存中變得越來越困難。所以,你需要一種方法來加載游戲中需要的部分,并卸載不需要的部分,而且你必須要在玩家不注意的情況下完成。
解決方案是流式傳輸,利用Unity的異步場(chǎng)景加載來實(shí)現(xiàn)。不過,你在實(shí)現(xiàn)過程中依然有可能會(huì)遇到一定的問題。下面這篇來自Meta的博文將向你介紹相關(guān)的使用技巧。注意,以下所有建議均基于Unity 2020.3.8f1中的行為。在Unity的其他版本中,性能結(jié)果可能不同。
為什么我的‘異步’加載仍會(huì)導(dǎo)致丟幀?
從磁盤加載場(chǎng)景可能需要很長(zhǎng)時(shí)間,尤其是在有大量網(wǎng)格和紋理的情況下。要讀取的數(shù)據(jù)非常多。這就是為什么Unity提供了一種異步加載場(chǎng)景的方法SceneManager.LoadSceneAsync()。這非常棒,因?yàn)槟悴槐卦诘却虞d數(shù)據(jù)時(shí)顯示加載屏幕,但你可能已經(jīng)注意到,當(dāng)你將allowSceneActivation flag設(shè)置為true時(shí),你會(huì)得到一個(gè)很長(zhǎng)的幀。你可能會(huì)問,“什么原因,這不是異步嗎?”。下面是原因:
-Unity中的所有對(duì)象都遵守Unity生命周期,例如Awake, OnEnable, Start, Update, OnDisable, OnDestroy。
-所有生命周期函數(shù)都在主線程執(zhí)行。
所以當(dāng)你激活場(chǎng)景時(shí),Unity必須為場(chǎng)景中的每個(gè)對(duì)象運(yùn)行Unity生命周期的第一步。
你可能會(huì)說,“但我沒有任何腳本附加到對(duì)象”。你需要知道的是,GameObjects和Transforms都存在Unity版本的“Awake”。無論是活動(dòng)的還是非活動(dòng)的,場(chǎng)景中的每個(gè)GameObject都會(huì)增加場(chǎng)景激活所需的時(shí)間。所以,這引出了我們的第一個(gè)技巧:
技巧1:減少場(chǎng)景中GameObject的數(shù)量
我運(yùn)行測(cè)試了異步加載不同數(shù)量GameObject的場(chǎng)景,并測(cè)量了將allowSceneActivation設(shè)置為true的幀長(zhǎng)度。以下是在Quest 2運(yùn)行的結(jié)果:
如你所見,場(chǎng)景激活所需的時(shí)間與場(chǎng)景中GameObject的數(shù)量呈線性關(guān)系。在這種情況下,活動(dòng)和非活動(dòng)的GameObject之間沒有區(qū)別。
你可能會(huì)問,如何減少場(chǎng)景中GameObject的數(shù)量?減少GameObject數(shù)量的一個(gè)好辦法,并且是提高性能的一個(gè)好辦法是:將盡可能多的靜態(tài)幾何體批處理成盡可能少的對(duì)象。第二,因?yàn)榧词故俏词褂玫膶?duì)象都需要時(shí)間加載,所以在Release之前請(qǐng)從場(chǎng)景中刪除所有不必要的/占位符對(duì)象。
技巧2:禁用場(chǎng)景中的GameObject
“但你剛才說,在我的場(chǎng)景中禁用或啟用GameObject并不重要?”這對(duì)于empty GameObject正確,但它不是適合所有一切。接到GameObject的每個(gè)組件都會(huì)花費(fèi)一定的時(shí)間。但是,時(shí)間的分布并不均勻。例如,ParticleSystem組件的激活時(shí)間比MeshFilter和MeshRenderer長(zhǎng),而TextMeshPro組件的激活時(shí)間比兩者加起來都長(zhǎng),因?yàn)樗仨氃诩せ顣r(shí)構(gòu)建網(wǎng)格:
禁用GameObjects后,你將推遲所述不同組件在使用前需要執(zhí)行的昂貴設(shè)置。下面是所有GameObject禁用時(shí)發(fā)生的情況:
當(dāng)然,為了獲得組件的好處,你需要激活它們,但在加載時(shí)禁用它們可允許你在schedule中啟用它們,這意味著你可以在多個(gè)幀滾動(dòng)激活時(shí)間,避免糟糕的幀問題。
技巧3:預(yù)編譯所有著色器
加載場(chǎng)景時(shí)可能會(huì)導(dǎo)致很大的問題,而非常容易避免的是著色器編譯。當(dāng)活動(dòng)對(duì)象第一次引用著色器變量時(shí),Unity將嘗試編譯它,這可能需要相當(dāng)長(zhǎng)的時(shí)間,特別是當(dāng)需要同時(shí)編譯多個(gè)著色器時(shí)。最好確保所有著色器都已預(yù)編譯,并在初始加載期間準(zhǔn)備就緒(可以被靜態(tài)加載屏幕屏蔽)。一種方法是用游戲中引用的每種材質(zhì)創(chuàng)建一個(gè)場(chǎng)景,然后首先將其加載到初始屏幕后面。確保涵蓋游戲中可能會(huì)更改Unity著色器關(guān)鍵字的所有不同變量,如reflection probes、light probes和direction light等。避免使用Shader.WarmupAll,因?yàn)樗鼘⒕幾g你的著色器的所有可能變量,而你不太可能在游戲中遇到它們中的大多數(shù)。
技巧4:小心意外的網(wǎng)格陷阱
盡管大多數(shù)網(wǎng)格都非常樂意與場(chǎng)景異步加載,但有一些條件會(huì)使網(wǎng)格加載在激活場(chǎng)景時(shí)出現(xiàn)故障。如果網(wǎng)格需要CPU讀取,則其激活時(shí)間將很長(zhǎng)。有一些因素會(huì)導(dǎo)致網(wǎng)格的CPU讀取,其中最明顯的是保持ReadWrite啟用狀態(tài)。另外,如果網(wǎng)格可蒙皮,則其需要CPU讀取。很難避免同時(shí)加載蒙皮網(wǎng)格,但你可以通過一定的技巧進(jìn)行避免。例如,一些模塊化角色系統(tǒng)將所有可能的部分包含在一個(gè)大型FBX文件中,這在運(yùn)行時(shí)將導(dǎo)致巨大的負(fù)載。相反,你最好將所有片段分解為單獨(dú)的網(wǎng)格,并在運(yùn)行時(shí)構(gòu)建模塊化角色。在最壞的情況下,最好將蒙皮網(wǎng)格從異步場(chǎng)景中完全移除,并在初始加載屏幕后面加載它們。
技巧5:在盡可能少的“根”游戲?qū)ο笙虑短子螒驅(qū)ο?但僅在加載時(shí))
如果所有游戲?qū)ο蠖记短自?ldquo;根”游戲?qū)ο笙,你將看到激活時(shí)間的改進(jìn):
Unity必須對(duì)位于場(chǎng)景根的每個(gè)對(duì)象進(jìn)行額外的處理。為了避免這種情況,只需將所有內(nèi)容放在單個(gè)或一小組“根”對(duì)象下,即可加快場(chǎng)景激活速度。
但是,嵌套對(duì)象在運(yùn)行時(shí)同樣有缺點(diǎn)。Unity將在多個(gè)線程上更新轉(zhuǎn)換,所以使用單個(gè)根對(duì)象實(shí)際上會(huì)降低性能,因?yàn)樗鼘⒍嗑程操作限制為單個(gè)線程。因此,最好在運(yùn)行時(shí)將嵌套對(duì)象“解包”到平面層次結(jié)構(gòu)中,或者使用少量根對(duì)象來保持多線程運(yùn)行時(shí)性能。
技巧6:回收利用你的GameObject
一種優(yōu)化方法是開始共享和重用對(duì)象。大多數(shù)Unity開發(fā)者已經(jīng)熟悉這項(xiàng)技術(shù)。本質(zhì)上,這個(gè)想法是創(chuàng)建一個(gè)通用重用對(duì)象池,并在玩家移動(dòng)時(shí)在游戲世界中移動(dòng)它們。例如,如果玩家在不同的地方看到木桶,你就會(huì)有一個(gè)木桶池,當(dāng)玩家走過一個(gè)木桶并移動(dòng)到另一個(gè)區(qū)域時(shí),在幕后你將同一個(gè)木桶移動(dòng)到新的位置,玩家一點(diǎn)都不知道。盡管聽起來很簡(jiǎn)單,但它存在復(fù)雜的部分。
首先,設(shè)計(jì)師需要將桶放置在該位置,因此你可能需要在場(chǎng)景中放置“BarrelProxy”腳本,以便池知道將其放置在何處。其次,如果你使用的是烘焙照明,你必須考慮光照如何影響你的桶。如果你的桶是可破壞的,它們不需要在你的光照貼圖中投射陰影,但它們可能仍然會(huì)接收陰影。在支持光照貼圖之前,需要實(shí)例化所有桶,記錄光照貼圖ID和Rect,并將其包含在代理組件中。然后在運(yùn)行時(shí),當(dāng)你從池中拉出桶時(shí),你應(yīng)該只需要將該光照貼圖數(shù)據(jù)應(yīng)用到渲染器。
這需要構(gòu)建自定義步驟來處理代理對(duì)象實(shí)例化/移除,我們可以使用這些步驟來執(zhí)行另一個(gè)步驟:從場(chǎng)景本身移除代理,并構(gòu)建代理位置的清單。然后,你可以將此清單作為每個(gè)場(chǎng)景中組件的一部分,或者作為游戲中某個(gè)地方包含的簡(jiǎn)單文本文件。
技巧7:發(fā)揮創(chuàng)意
如果前面的6個(gè)技巧不足以實(shí)現(xiàn)場(chǎng)景的無縫過渡,那么你是時(shí)候發(fā)揮創(chuàng)意了。你可以決定什么對(duì)你的作品最有意義,并創(chuàng)建最適合你的解決方案。場(chǎng)景包含的越少,加載的速度就越快,因此邏輯結(jié)論可能是進(jìn)一步減少場(chǎng)景的使用。也許你有一個(gè)構(gòu)建步驟可以將每個(gè)場(chǎng)景分割成若干子場(chǎng)景,每個(gè)子場(chǎng)景可以在不掛接的情況下加載。也許解決方案只是將場(chǎng)景用于靜態(tài)幾何體,其他所有內(nèi)容都將在運(yùn)行時(shí)作為預(yù)設(shè)加載。如果你能想出一個(gè)有創(chuàng)意的解決方案,請(qǐng)務(wù)必向社區(qū)分享。
文章內(nèi)容僅供閱讀,不構(gòu)成投資建議,請(qǐng)謹(jǐn)慎對(duì)待。投資者據(jù)此操作,風(fēng)險(xiǎn)自擔(dān)。
近日,德國(guó)柏林國(guó)際電子消費(fèi)品展覽會(huì)(IFA2024)隆重舉辦。憑借在核心技術(shù)、產(chǎn)品設(shè)計(jì)及應(yīng)用方面的創(chuàng)新變革,全球領(lǐng)先的智能終端企業(yè)TCL實(shí)業(yè)成功斬獲兩項(xiàng)“IFA全球產(chǎn)品設(shè)計(jì)創(chuàng)新大獎(jiǎng)”金獎(jiǎng),有力證明了其在全球市場(chǎng)的強(qiáng)大影響力。
近日,中國(guó)家電及消費(fèi)電子博覽會(huì)(AWE 2024)隆重開幕。全球領(lǐng)先的智能終端企業(yè)TCL實(shí)業(yè)攜多款創(chuàng)新技術(shù)和新品亮相,以敢為精神勇闖技術(shù)無人區(qū),斬獲四項(xiàng)AWE 2024艾普蘭大獎(jiǎng)。
“以前都要去窗口辦,一套流程下來都要半個(gè)月了,現(xiàn)在方便多了!”打開“重慶公積金”微信小程序,按照提示流程提交相關(guān)材料,僅幾秒鐘,重慶市民曾某的賬戶就打進(jìn)了21600元。
由世界人工智能大會(huì)組委會(huì)、上海市經(jīng)信委、徐匯區(qū)政府、臨港新片區(qū)管委會(huì)共同指導(dǎo),由上海市人工智能行業(yè)協(xié)會(huì)聯(lián)合上海人工智能實(shí)驗(yàn)室、上海臨港經(jīng)濟(jì)發(fā)展(集團(tuán))有限公司、開放原子開源基金會(huì)主辦的“2024全球開發(fā)者先鋒大會(huì)”,將于2024年3月23日至24日舉辦。