这篇文章主要为大家详细介绍了Unity实现离线计时器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了Unity中Instantiate实例化物体卡顿问题的解决方法,供大家参考,具体内容如下
一、前言
当在执行多次Instantiate实例化物体时,会卡顿严重甚至在移动端会导致程序崩溃
因为Instantiate会产生大量的GC,使CPU过高,导致崩溃
下面是一段测试代码:当我们按下按键时实例化100000个预制体
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查看性能
发现在实例化物体的那一帧产生了3.8MB的GC,而正常来说每帧的GC不能超过2KB,产生如此高的GC在移动端会导致内存溢出从而崩溃闪退。更可怕的是这一帧用时1519.24毫秒也就是1.5秒所以程序在此帧会出现卡顿现象
二、解决方法
卡顿或程序崩溃的原因就是在某一帧中产生了大量的GC
所以可以把一帧的操作分帧进行
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);
   }
  }
 }
}
三、协程中几种yield reutrn的执行顺序
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");
 }
}
经过测试,得出以下结论
- WaitForFixedUpdate在一帧的FixedUpdate后Update前调用
 - WaitForNull和Wait0在一帧的Update后LateUpdate前调用
 - WaitForEndFrame在会在一帧的LateUpdate后调用
 
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持得得之家。
本文标题为:Unity中Instantiate实例化物体卡顿问题的解决
				
        
 
            
        - Oracle中for循环的使用方法 2023-07-04
 - Unity3D实现渐变颜色效果 2023-01-16
 - 在C# 8中如何使用默认接口方法详解 2023-03-29
 - C# 使用Aspose.Cells 导出Excel的步骤及问题记录 2023-05-16
 - .NET CORE DI 依赖注入 2023-09-27
 - WPF使用DrawingContext实现绘制刻度条 2023-07-04
 - 如何使用C# 捕获进程输出 2023-03-10
 - user32.dll 函数说明小结 2022-12-26
 - Unity Shader实现模糊效果 2023-04-27
 - c# 模拟线性回归的示例 2023-03-14
 
						
						
						
						
						
				
				
				
				