zoukankan      html  css  js  c++  java
  • Unity C# 对象池

      1 using System.Collections.Generic;
      2 using UnityEngine;
      3 
      4 namespace TMoonObjectPool
      5 {
      6     /// <summary>
      7     /// 对象池
      8     /// </summary>
      9     public class GameObjectPool
     10     {
     11         /// <summary>
     12         /// 对象池的名字
     13         /// </summary>
     14         public string name = string.Empty;
     15 
     16         /// <summary>
     17         /// 对象池拥有的对象
     18         /// </summary>
     19         public GameObject obj = null;
     20 
     21         /// <summary>
     22         /// 对有效的对象栈存储
     23         /// </summary>
     24         private Stack<GameObject> available;
     25 
     26         /// <summary>
     27         /// 保存所有的对象
     28         /// </summary>
     29         private List<GameObject> all;
     30 
     31         /// <summary>
     32         /// 构造函数初始化
     33         /// </summary>
     34         /// <param name="name"></param>
     35         /// <param name="obj"></param>
     36         public GameObjectPool(string name, GameObject obj)
     37         {
     38             this.name = name;
     39             this.obj = obj;
     40             available = new Stack<GameObject>();
     41             all = new List<GameObject>();
     42         }
     43 
     44         /// <summary>
     45         /// 从对象池中分配一个对象
     46         /// </summary>
     47         /// <returns></returns>
     48         public GameObject Allocate(Vector3 position, Quaternion rotation)
     49         {
     50 
     51             GameObject go;
     52 
     53             // 创建对象
     54             if (available.Count == 0)
     55             {
     56                 go = GameObject.Instantiate(obj, position, rotation);
     57                 all.Add(go);
     58             }
     59             // 使用已存在的
     60             else
     61             {
     62                 go = available.Pop();
     63                 go.transform.position = position;
     64                 go.transform.rotation = rotation;
     65             }
     66 
     67             //激活对象并发送消息给对象已激活执行回调
     68             go.SetActive(true);
     69             //MessageDispatcher.SendMessage(go.name or go.tag);
     70 
     71             return go;
     72         }
     73 
     74         /// <summary>
     75         /// 从对象池中预先加载对象
     76         /// </summary>
     77         /// <param name="count">预先加载数量的数目</param>
     78         public void Preload(int count)
     79         {
     80             GameObject[] gos = new GameObject[count];
     81             GameObject parent = new GameObject(obj.name);
     82             // 创建预先加载的对象
     83             for (int i = 0; i < count; i++)
     84             {
     85                 gos[i] = Allocate(Vector3.zero, Quaternion.identity);
     86                 gos[i].transform.parent = parent.transform;
     87             }
     88 
     89             for (int i = 0; i < count; i++)
     90             {
     91                 Release(gos[i]);
     92             }
     93         }
     94 
     95         /// <summary>
     96         /// 把对象回收到对象池中去
     97         /// </summary>
     98         /// <param name="obj"></param>
     99         public void Release(GameObject obj)
    100         {
    101             if (!available.Contains(obj))
    102             {
    103                 available.Push(obj);
    104 
    105                 //禁用对象并发送消息给对象已禁用执行回调
    106                 //MessageDispatcher.SendMessage(go.name or go.tag);
    107                 obj.SetActive(false);
    108             }
    109         }
    110 
    111         /// <summary>
    112         /// 对象池回收所有的对象
    113         /// </summary>
    114         public void ReleaseAll()
    115         {
    116             for (int i = 0; i < all.Count; i++)
    117             {
    118                 GameObject go = all[i];
    119                 if (go != null && go.activeInHierarchy)
    120                 {
    121                     Release(go);
    122                 }
    123             }
    124         }
    125 
    126         /// <summary>
    127         /// 清理对象池
    128         /// </summary>
    129         public void Clear()
    130         {
    131             ReleaseAll();
    132             available.Clear();
    133             all.Clear();
    134         }
    135 
    136         /// <summary>
    137         /// 返回已激活的对象
    138         /// </summary>
    139         /// <returns></returns>
    140         public int GetActiveCount()
    141         {
    142             return all.Count - available.Count;
    143         }
    144 
    145         /// <summary>
    146         /// 返回可用对象的数目
    147         /// </summary>
    148         /// <returns></returns>
    149         public int GetAvailableCount()
    150         {
    151             return available.Count;
    152         }
    153 
    154         /// <summary>
    155         /// 返回对象池中的对象
    156         /// </summary>
    157         /// <returns></returns>
    158         public GameObject GetObject()
    159         {
    160             return obj;
    161         }
    162     }
    163 }
    GameObjectPool
     1 using System.Collections;
     2 using System.Collections.Generic;
     3 using TMoonObjectPool;
     4 using UnityEngine;
     5 
     6 namespace TMoonObjectPool
     7 {
     8     /// <summary>
     9     /// 对象池管理类
    10     /// </summary>
    11     public class PoolManager
    12     {
    13         private static PoolManager instance = null;
    14         public static PoolManager Instance
    15         {
    16             get
    17             {
    18                 if (instance == null)
    19                 {
    20                     instance = new PoolManager();
    21                 }
    22                 return instance;
    23             }
    24         }
    25 
    26         private List<GameObjectPool> pools = null;
    27 
    28         private PoolManager() { pools = new List<GameObjectPool>(); }
    29 
    30         //创建一个对象池
    31         public GameObjectPool Create(string name, GameObject obj)
    32         {
    33             GameObjectPool pool = new GameObjectPool(name, obj);
    34             pools.Add(pool);
    35             return pool;
    36         }
    37 
    38         //移除一个对象池
    39         public void Remove(string name)
    40         {
    41             int index = pools.FindIndex((pool) => pool.name == name);
    42             pools[index].Clear();
    43             pools.RemoveAt(index);
    44         }
    45 
    46         //移除所有的对象池
    47         public void RemoveAll()
    48         {
    49             pools.Clear();
    50         }
    51 
    52         /// <summary>
    53         /// 得到一个对象池
    54         /// </summary>
    55         /// <param name="name">对象池的名字</param>
    56         /// <returns></returns>
    57         public GameObjectPool GetPool(string name)
    58         {
    59             return pools.Find((pool) => pool.name == name);
    60         }
    61     }
    62 }
    PoolManager

    示例代码:

     1 using System;
     2 using System.Collections;
     3 using System.Collections.Generic;
     4 using TMoonObjectPool;
     5 using UnityEngine;
     6 
     7 public class test : MonoBehaviour
     8 {
     9     public GameObject go;
    10     private GameObjectPool pool;
    11     void Start()
    12     {
    13         pool = PoolManager.Instance.Create("go", go);
    14         pool.Preload(5);
    15     }
    16 
    17     void Update()
    18     {
    19         if (Input.GetMouseButtonDown(0))
    20         {
    21             pool.Allocate(Vector3.zero,Quaternion.identity);
    22         }
    23 
    24         if (Input.GetKeyDown(KeyCode.R))
    25         {
    26             pool.ReleaseAll();
    27         }
    28     }
    29 }
    示例代码

    今天看了下Unity UGUI的源码,发现了一个对象池的工具类,觉得写得又简单又好,在下面直接贴代码上来了。

     1 using System.Collections.Generic;
     2 using UnityEngine.Events;
     3 
     4 namespace UnityEngine.UI
     5 {
     6     internal class ObjectPool<T> where T : new()
     7     {
     8         private readonly Stack<T> m_Stack = new Stack<T>();
     9         private readonly UnityAction<T> m_ActionOnGet;
    10         private readonly UnityAction<T> m_ActionOnRelease;
    11 
    12         public int countAll { get; private set; }
    13         public int countActive { get { return countAll - countInactive; } }
    14         public int countInactive { get { return m_Stack.Count; } }
    15 
    16         public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease)
    17         {
    18             m_ActionOnGet = actionOnGet;
    19             m_ActionOnRelease = actionOnRelease;
    20         }
    21 
    22         public T Get()
    23         {
    24             T element;
    25             if (m_Stack.Count == 0)
    26             {
    27                 element = new T();
    28                 countAll++;
    29             }
    30             else
    31             {
    32                 element = m_Stack.Pop();
    33             }
    34             if (m_ActionOnGet != null)
    35                 m_ActionOnGet(element);
    36             return element;
    37         }
    38 
    39         public void Release(T element)
    40         {
    41             if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element))
    42                 Debug.LogError("Internal error. Trying to destroy object that is already released to pool.");
    43             if (m_ActionOnRelease != null)
    44                 m_ActionOnRelease(element);
    45             m_Stack.Push(element);
    46         }
    47     }
    48 }
    ObjectPool
  • 相关阅读:
    BZOJ 4445 [Scoi2015]小凸想跑步:半平面交
    BZOJ 3931 [CQOI2015]网络吞吐量:最大流【拆点】
    BZOJ 3698 XWW的难题:有上下界的最大流
    AtCoder ARC097C Sorted and Sorted:dp
    BZOJ 1835 [ZJOI2010]base 基站选址:线段树优化dp
    BZOJ 3329 Xorequ:数位dp + 矩阵快速幂
    BZOJ 1492 [NOI2007]货币兑换Cash:斜率优化dp + cdq分治
    BZOJ 4726 [POI2017]Sabota?:树形dp
    BZOJ 1185 [HNOI2007]最小矩形覆盖:凸包 + 旋转卡壳
    存一些东西
  • 原文地址:https://www.cnblogs.com/SeaSwallow/p/6550920.html
Copyright © 2011-2022 走看看