Unity中Instantiate實(shí)例化物體卡頓問題的解決
本文實(shí)例為大家分享了Unity中Instantiate實(shí)例化物體卡頓問題的解決方法,供大家參考,具體內(nèi)容如下
一、前言
當(dāng)在執(zhí)行多次Instantiate實(shí)例化物體時(shí),會(huì)卡頓嚴(yán)重甚至在移動(dòng)端會(huì)導(dǎo)致程序崩潰
因?yàn)镮nstantiate會(huì)產(chǎn)生大量的GC,使CPU過高,導(dǎo)致崩潰
下面是一段測(cè)試代碼:當(dāng)我們按下按鍵時(shí)實(shí)例化100000個(gè)預(yù)制體
using UnityEngine; public class Test : MonoBehaviour { public GameObject prefab; private void Update() { if (Input.GetKeyDown(KeyCode.A)) { Generate(); } } private void Generate() { for (int i = 0; i < 100000; i++) { Instantiate(prefab); } } }
運(yùn)行后通過profiler查看性能
發(fā)現(xiàn)在實(shí)例化物體的那一幀產(chǎn)生了3.8MB的GC,而正常來說每幀的GC不能超過2KB,產(chǎn)生如此高的GC在移動(dòng)端會(huì)導(dǎo)致內(nèi)存溢出從而崩潰閃退。更可怕的是這一幀用時(shí)1519.24毫秒也就是1.5秒所以程序在此幀會(huì)出現(xiàn)卡頓現(xiàn)象
二、解決方法
卡頓或程序崩潰的原因就是在某一幀中產(chǎn)生了大量的GC
所以可以把一幀的操作分幀進(jìn)行
using UnityEngine; using System.Collections; public class Test : MonoBehaviour { public GameObject prefab; private void Update() { if (Input.GetKeyDown(KeyCode.A)) { StartCoroutine(Generate()); } } private IEnumerator Generate() { int tempCount = 0; for (int i = 0; i < 100000; i++) { if (tempCount <= 5000) { Instantiate(prefab); tempCount++; } else { tempCount = 0; yield return new WaitForEndOfFrame(); Instantiate(prefab); } } } }
三、協(xié)程中幾種yield reutrn的執(zhí)行順序
using UnityEngine; using System.Collections; public class Test : MonoBehaviour { private void Start() { StartCoroutine(WaitForNull()); StartCoroutine(WaitForEndFrame()); StartCoroutine(Wait0()); StartCoroutine(WaitForFixedUpdate()); } private IEnumerator WaitForNull() { Debug.Log("[1]WaitForNull:" + Time.frameCount); yield return null; Debug.Log("[2]WaitForNull:" + Time.frameCount); } private IEnumerator WaitForEndFrame() { Debug.Log("[1]WaitForEndFrame:" + Time.frameCount); yield return new WaitForEndOfFrame(); Debug.Log("[2]WaitForEndFrame:" + Time.frameCount); } private IEnumerator Wait0() { Debug.Log("[1]Wait0:" + Time.frameCount); yield return 0; Debug.Log("[2]Wait0:" + Time.frameCount); } private IEnumerator WaitForFixedUpdate() { Debug.Log("[1]WaitForFixedUpdate:" + Time.frameCount); yield return new WaitForFixedUpdate(); Debug.Log("[2]WaitForFixedUpdate:" + Time.frameCount); } private void Update() { Debug.Log("update"); } private void FixedUpdate() { Debug.Log("FixedUpdate"); } private void LateUpdate() { Debug.Log("LateUpdate"); } }
經(jīng)過測(cè)試,得出以下結(jié)論
- WaitForFixedUpdate在一幀的FixedUpdate后Update前調(diào)用
- WaitForNull和Wait0在一幀的Update后LateUpdate前調(diào)用
- WaitForEndFrame在會(huì)在一幀的LateUpdate后調(diào)用
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#中Equals和GetHashCode使用及區(qū)別
這篇文章主要介紹了C#中Equals和GetHashCode使用及區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02C#中GraphicsPath的Warp方法用法實(shí)例
這篇文章主要介紹了C#中GraphicsPath的Warp方法用法,實(shí)例分析了Warp方法的相關(guān)使用技巧,需要的朋友可以參考下2015-06-06C# SendMail發(fā)送郵件功能實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了C# SendMail發(fā)送郵件功能實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Unity編輯器資源導(dǎo)入處理函數(shù)OnPostprocessAudio使用案例
這篇文章主要為大家介紹了Unity編輯器資源導(dǎo)入處理函數(shù)OnPostprocessAudio使用案例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08