当前位置:网站首页>Unity3d: special effect object pool, timeout delete GameObject in the pool, GC weight
Unity3d: special effect object pool, timeout delete GameObject in the pool, GC weight
2022-07-23 12:45:00 【Sixi Liyu】
Technical points :
- Unused particles return to the buffer pool
- Create a pool according to the name of a single particle , When a The last operation time on the pool ( Recovery object ) Threshold exceeded , Delete one in the pool every once in a while GameObject, It can be configured for a single particle , Frequently used , Longer dwell time
- A complete pool is deleted , increase GC A weight ,GC When the weight reaches the maximum value, call System.GC.Collect()
Have a problem :
- Parent node OnDisable, You cannot set the parent object of a child node
Cannot set the parent of the GameObject ''XXX“ while activating or deactivating the parent GameObject “XXX” , Because when the parent object enters the recycling pool , The code is modifying the parent node of the child node of this object . The modification method is : Set a layer of empty objects for child nodes - After recycling, transfer it out of the pool , Particles show only half , Or don't show
Every time the particles are taken out , If the last particle is in scroll Use in , Cutting shader Under the influence of , There will be half cutting , To reset the particle clipping area
public void ResetMaskParams(Material mat)
{
mat.SetFloat("_MinX", -1);
mat.SetFloat("_MinY", -1);
mat.SetFloat("_MaxX", 1);
mat.SetFloat("_MaxY", 1);
}
- Some particles have special treatment , For example, destroy sub objects when used up ; Or mounting scripts will lose references , Do not put it into the buffer pool
Code
Get particles
A simple test , Really use resid Instead of objPrefab, And use Assetbundle Synchronous loading
public GameObject GetEffect(GameObject objPrefab)
{
string name = GetNoCloneName(objPrefab.name);
GameObject obj = null;
if (m_dicPool.ContainsKey(name))
{
if (m_dicPool[name] != null && m_dicPool[name].Count > 0)
{
obj = m_dicPool[name].Dequeue();
while (obj == null && m_dicPool[name].Count > 0)
{
obj = m_dicPool[name].Dequeue();
if (obj != null)
{
//return obj;
break;
}
}
if (obj == null)
{
obj = GameObject.Instantiate(objPrefab) as GameObject;
}
}
else
{
obj = GameObject.Instantiate(objPrefab) as GameObject;
}
}
else
{
m_dicPool[name] = new Queue<GameObject>(m_count);
obj = GameObject.Instantiate(objPrefab) as GameObject;
}
obj.SetActive(true);
SetInDicUse(obj);
return obj;
}
Recycling particles
public void RecycleEffect(GameObject obj)
{
if (obj == null)
{
return;
}
// Add the name of the particles to be filtered and not recycled , Or conditions
string name = GetNoCloneName(obj.name);
m_lastUsedTime[name] = Time.time;
SetOutDicUse(obj);
obj.transform.SetParent(GetEffectPoolObj());
obj.SetActive(false);
if (m_dicPool.ContainsKey(name))
{
if (m_dicPool[name] == null)
{
m_dicPool[name] = new Queue<GameObject>(m_count);
}
m_dicPool[name].Enqueue(obj);
}
else
{
m_dicPool[name] = new Queue<GameObject>(m_count);
m_dicPool[name].Enqueue(obj);
}
}
The particle pool timed out and is no longer used ,Destroy One GameObject
private void FixedUpdate()
{
foreach (var item in m_lastUsedTime)
{
string keyName = item.Key;
float lastTime = item.Value;
if (m_dicUse.ContainsKey(keyName) && m_dicUse[keyName].Count == 0)
{
if (m_dicPool.ContainsKey(keyName))
{
if (m_dicPool[keyName].Count > 0)// There are still free objects in a pool
{
if (Time.time - lastTime > GetDeleOneObjTimeClip(m_dicPool[keyName].Count)) // Timeout to remove an idle object
{
GameObject idleObj = m_dicPool[keyName].Dequeue();
GameObject.Destroy(idleObj);
timeUpdateList.Add(keyName);
}
}
else// There are no free objects in a pool
{
if (Time.time - lastTime > mResReleaseTime)
{
releaseList.Add(keyName);
}
}
}
}
}
for (int i = 0; i < timeUpdateList.Count; i++)
{
m_lastUsedTime[timeUpdateList[i]] = Time.time; // Last time a certain... In the buffer pool was deleted obj Time for
}
GC A weight
public void AddUnloadWeights(int nWeights = 1)
{
m_nSumWeights += nWeights;
}
void Update()
{
// Every time 60 Frame performs a detection
if (Time.frameCount % CHECK_INTERVAL_FRAME == 0)
{
TryUnloadUnusedAssets();
}
}
void TryUnloadUnusedAssets()
{
if ((Time.realtimeSinceStartup - m_fLastUnloadTime >= m_nMaxInterval)
|| (m_nSumWeights >= m_nWeightsThreshold))
{
DoUnloadUnusedAssets();
}
}
void DoUnloadUnusedAssets()
{
Resources.UnloadUnusedAssets();
System.GC.Collect();
m_nSumWeights = 0;
m_fLastUnloadTime = Time.realtimeSinceStartup;
}
Source code
https://github.com/luoyikun/UnityForTest
EffectPoolMgr.cs
边栏推荐
- Doubts about using the incluxdb database
- 剖析Redis集群
- 前缀和 LeetCode2100. 适合打劫银行的日子
- OSPF的链路扩展配置
- C语言也能写植物大战僵尸
- 大白话说说synchronized关键词的三种用法
- Sql Server性能分析,查看慢查询
- Using one-way linked list to realize queue
- unity3d:Assetbundle模拟加载,同步加载,异步加载,依赖包加载,自动标签,AB浏览器,增量打包
- Explain the flow control mechanism and congestion control mechanism of TCP in detail
猜你喜欢
随机推荐
Explain various network protocols in detail
htpasswd作用
The CUDA version of pytorch installed by anconda is inconsistent with the CUDA version of the system
unity3d:UGUI源码EventSystem输入系统常见问题
浅析UDP协议和TCP协议
直白理解一文搞定http协议缓存
[fee of AUTOSAR (difference between nonvolatile memory flash and EEPROM)]
LeetCode题解汇总
APISIX的源码安装与使用
如何解决if语句太多
HCIP-第一次实验
剑指offer 青蛙跳楼梯
HCIP---BGP相关配置(联邦篇)
C语言:基于顺序表的学生管理系统,超级详细,全部都有注释,看完不懂来扇我。
WebSocket 协议讲解
关于搭建Hybrid App所需要的基础技术一文
@RequiredArgsConstructor注解使用
HCIP---MGRE环境下的OSPF综合实验
C custom set
Explain the establishment of TCP connection in detail





![[AUTOSAR storage stack NVM]](/img/7a/15e01f8ace647b55e11e764dba1b64.png)
![[AUTOSAR DCM 1. module introduction (DSL, DSD, DSP)]](/img/99/55b3162ad061fbd00145d0b6810592.png)

