Unity中Instantiate實例化物體卡頓問題的解決
本文實例為大家分享了Unity中Instantiate實例化物體卡頓問題的解決方法,供大家參考,具體內(nèi)容如下
一、前言
當(dāng)在執(zhí)行多次Instantiate實例化物體時,會卡頓嚴(yán)重甚至在移動端會導(dǎo)致程序崩潰
因為Instantiate會產(chǎn)生大量的GC,使CPU過高,導(dǎo)致崩潰
下面是一段測試代碼:當(dāng)我們按下按鍵時實例化100000個預(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);
}
}
}
運行后通過profiler查看性能

發(fā)現(xiàn)在實例化物體的那一幀產(chǎn)生了3.8MB的GC,而正常來說每幀的GC不能超過2KB,產(chǎn)生如此高的GC在移動端會導(dǎo)致內(nèi)存溢出從而崩潰閃退。更可怕的是這一幀用時1519.24毫秒也就是1.5秒所以程序在此幀會出現(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)過測試,得出以下結(jié)論
- WaitForFixedUpdate在一幀的FixedUpdate后Update前調(diào)用
- WaitForNull和Wait0在一幀的Update后LateUpdate前調(diào)用
- WaitForEndFrame在會在一幀的LateUpdate后調(diào)用
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C# wpf Grid中實現(xiàn)控件拖動調(diào)整大小的示例代碼
本文主要介紹了C# wpf Grid中實現(xiàn)控件拖動調(diào)整大小的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
Unity3D UI Text得分?jǐn)?shù)字增加的實例代碼
這篇文章主要介紹了Unity3D UI Text得分?jǐn)?shù)字增加方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
C# 并發(fā)控制框架之單線程環(huán)境下實現(xiàn)每秒百萬級調(diào)度
本文介紹了一款專為工業(yè)自動化及機器視覺開發(fā)的C#并發(fā)流程控制框架,通過模仿Go語言并發(fā)模式設(shè)計,支持高頻調(diào)度及復(fù)雜任務(wù)處理,已在多個項目中驗證其穩(wěn)定性和可靠性2024-10-10
C#實現(xiàn)微信公眾號群發(fā)消息(解決一天只能發(fā)一次的限制)實例分享
經(jīng)過幾天研究網(wǎng)上的代碼和謝燦大神的幫忙,今天終于用C#實現(xiàn)了微信公眾號群發(fā)消息,現(xiàn)在分享一下2013-09-09

