unity对象缓存技术ObjectPool
创始人
2024-11-16 03:36:05
0

首先先看下通过ObjectPool实现的一个小的效果,效果如下

“”

通过视频我们可以在Hierarchy窗口看到Sphere对象列表,出现,隐藏然后又active,然后又隐藏。
具体实现逻辑如下

step1 创建子弹预制体并绑定脚本。

子弹的预制体比较简单这里就不列举了,脚本我们呢取名字为BulletController,脚本处理如下:

 public class BulletController : MonoBehaviour {     public float speed;     public float exitTime;     public float radiam;     public float timer;       public void ResetTime()     {         timer = 0f;     }      void Update()     {         timer += Time.deltaTime;         if (timer > exitTime)         {             PlayerController.bulletPool.Release(gameObject);             // Destroy(gameObject);         }         transform.position += new Vector3(speed * Time.deltaTime * Mathf.Sign(radiam+ timer*5),             speed * Time.deltaTime * Mathf.Cos(radiam + timer * 5), 0);     } } 

基本逻辑实现就是在update里面做时间累加,累加到一定时间就销毁物体,但是3D物体的创建销毁会造成UI的堵塞,因此我们这边使用对象池调用对象池的Release方法回收物体。ResetTime作用是重置物体状态。

step2 创建子弹发射器并通过对象池实现子弹的发射收集过程

//创建对象池并添加回调   //defaultCapacity默认开辟对象数量(unity会给我们在内存开辟空间但并不会实例化对象) // maxSize 对象池最大容量  ulletPool = new ObjectPool(CreateFunc, ActionOnGet, ActionOnRelease, ActionOnDestroy, true,    defaultCapacity: 10, maxSize:20);     //创建物体回调 在这个回调中当对象池内容不够时会被回调  private GameObject CreateFunc()  {     return  Instantiate(bulletPrefab, _MTransform.position, Quaternion.identity);  }  //当使用物体时调用 这里我们的处理是让物体显示  private void ActionOnGet(GameObject @object)  {      @object.SetActive(true);  } //当物体回收的时候调用这块处理是让物体隐藏 private void ActionOnRelease(GameObject @object) {     @object.SetActive(false); }  //当要创建的物体超过对象池容量的时候  //然后对象池需要回收掉需要的对象多余创建的对象会调用这个回调通知销毁  private void ActionOnDestroy(GameObject @object)  {      Destroy( @object );  } 

通过上面的处理我们理解了对象池各个回调的作用以及调用时机,下面我们看下调用逻辑

step3 调用对象池处理

这块处理也是很简单的

btn.onClick.AddListener(() => {     int d = 2;     float d_angle = 360 / d;     float radium = 360 / d * Mathf.PI / 180;     for (int i = 0; i < d; i++)     {         GameObject g = bulletPool.Get();         BulletController bullet = g.GetComponent();         bullet.transform.position = _MTransform.position;         bullet.transform.rotation = Quaternion.identity;         bullet.radiam = radium * i;         bullet.ResetTime();     } }); 

这块处理也是很简单for循环创建物体,当然我们不是实例化预制体也不是new Object而是通过**bulletPool.Get()**这个方法取到对象,并给对象的脚本赋默认值。

step4总结
最后我们总结一下ObjectPool使用
1,.首先创建对象,并完成各个回调处理
2.然后在需要获取物体的地方使用 ObjectPool.Get() 获取物体
3.然后当物体需要销毁的时候通过 ObjectPool.Release(gameObject) 回收物体(ObjectPool会根据设置的阈值判定是回收物体还是销毁物体)

最后把PlayerController的源码放在这里

public class PlayerController : MonoBehaviour {     [SerializeField]     private float speed;     [SerializeField]     private GameObject bulletPrefab;     [SerializeField]     private Button btn;      private Transform _MTransform;     public static ObjectPool bulletPool;      void Start()     {         _MTransform = transform;         bulletPool = new ObjectPool(CreateFunc, ActionOnGet, ActionOnRelease, ActionOnDestroy, true,             defaultCapacity: 10, maxSize:20);         btn.onClick.AddListener(() => {             int d = 2;             float d_angle = 360 / d;             float radium = 360 / d * Mathf.PI / 180;             for (int i = 0; i < d; i++)             {                 /* GameObject g = Instantiate(bulletPrefab, _MTransform.position, Quaternion.identity);                  BulletController bullet = g.GetComponent();*/                 GameObject g = bulletPool.Get();                 BulletController bullet = g.GetComponent();                 bullet.transform.position = _MTransform.position;                 bullet.transform.rotation = Quaternion.identity;                 bullet.radiam = radium * i;                 bullet.ResetTime();             }         });     }      private GameObject CreateFunc()     {         GameObject g = Instantiate(bulletPrefab, _MTransform.position, Quaternion.identity);         BulletController bullet = g.GetComponent();         Debug.Log("CreateFunc  " + bulletPool.CountInactive);         return g;     }      private void ActionOnGet(GameObject @object)     {         @object.SetActive(true);         Debug.Log("ActionOnGet  " + bulletPool.CountInactive);     }     private void ActionOnRelease(GameObject @object)     {         @object.SetActive(false);         Debug.Log("ActionOnRelease  " + bulletPool.CountInactive);     }      private void ActionOnDestroy(GameObject @object)     {         Destroy( @object );         Debug.Log("ActionOnDestroy  " + bulletPool.CountInactive);     } } 

相关内容

热门资讯

玩家攻略,金花房卡专卖店九酷众... 微信游戏中心:九酷众娱房卡在哪里买打开微信,添加客服微信【88355042】,进入游戏中心或相关小程...
正规平台有哪些,金花房卡批发价... 正规平台有哪些,金花房卡批发价火神大厅/房卡链接怎么获取Sa9Ix苹果iPhone 17手机即将进入...
ia攻略/金花房卡如何购买嫦娥... 嫦娥大厅是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:【3329006910】或QQ:332900...
推荐一款!牛牛充值房卡海草众厅... 海草众厅房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 3、根...
一分钟了解!金花房卡出售红桃众... 一分钟了解!金花房卡出售红桃众娱/微信链接房卡充值链接红桃众娱是一款非常受欢迎的游戏,咨询房/卡添加...
我来教你/金花房卡制作链接熊猫... 我来教你/金花房卡制作链接熊猫大厅/微信链接房卡批发价Sa9Ix苹果iPhone 17手机即将进入量...
科技实测!金花房卡出售新八戒/... 新八戒房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 3、根据...
ia攻略/斗牛房卡充值乐乐大厅... 微信游戏中心:乐乐大厅房卡在哪里买打开微信,添加客服微信【88355042】,进入游戏中心或相关小程...
ia攻略/金花房卡批发嫦娥大厅... 嫦娥大厅是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:【3329006910】或QQ:332900...
头条推荐!金花房卡出售乐乐大厅... 头条推荐!金花房卡出售乐乐大厅//全网房卡低价售Sa9Ix苹果iPhone 17手机即将进入量产阶段...
重大通报,金花房卡制作链接黄帝... 您好!微信黄帝大厅大厅链接获取房卡可以通过以下几种方式购买: 1.微信渠道:(黄帝大厅)大厅介绍:...
头条推荐!金花房卡是正规的兄弟... 兄弟大厅/新道游房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 ...
科技实测!怎么买斗牛房卡龙马大... 龙马大厅是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:【3329006910】或QQ:332900...
科技实测!游戏推荐斗牛房卡出售... 您好!微信悠悠众娱大厅链接获取房卡可以通过以下几种方式购买: 1.微信渠道:(悠悠众娱)大厅介绍:...
玩家攻略,怎么买斗牛房卡至尊大... 今 日消息,至尊大厅房卡添加微信33549083 苹果今日发布了 iOS 16.1 正式版更新,简单...
玩家攻略,游戏推荐牛牛房卡出售... 金牛座厅/新西部房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 ...
IA解析/怎么买斗牛房卡海蓝大... IA解析/怎么买斗牛房卡海蓝大厅/开群怎么买房卡海蓝大厅是一款非常受欢迎的游戏,咨询房/卡添加微信:...
我来教你/金花房卡批发价龙王大... 我来教你/金花房卡批发价龙王大厅/房卡怎么搞Sa9Ix苹果iPhone 17手机即将进入量产阶段。有...
我来教你/牛牛房卡制作链接卡农... 今 日消息,卡农大厅房卡添加微信33549083 苹果今日发布了 iOS 16.1 正式版更新,简单...
IA解析/金花房卡专卖店芝麻大... 微信游戏中心:芝麻大厅房卡在哪里买打开微信,添加客服微信【88355042】,进入游戏中心或相关小程...