Unity3d 对象池、子对象池的实现

来源:互联网 发布:表表外业务 知乎 编辑:程序博客网 时间:2024/06/03 15:58

ObjectPool.cs 对象池的实现

码云简单示例:https://gitee.com/xianglinlove/ObjectPool

using System.Collections.Generic;using UnityEngine;public class ObjectPool : Singleton<ObjectPool>{    // Resources目录    public string ResourceDir = "";    // 保存预设资源和子池子    Dictionary<string, SubPool> _pools = new Dictionary<string, SubPool>();     // 取 name是预设的名字    public GameObject Spawn(string name)    {        // 判断对应的子池子是否存在        // 不存在就创建一个子池子        // 然后返回        if(!_pools.ContainsKey(name))            RegistreNewPool(name);        SubPool pool = _pools[name];        return pool.Spawn();    }    // 回收    public void UnSpawn(GameObject go)    {        // 只回收池子中存在的对象        // 遍历字典,找到包含go的子池子        // 调用子池子的UnSpawn方法回收        SubPool subPool = null;        foreach (var pool in _pools.Values)        {            if (pool.Contains(go))            {                subPool = pool;                break;            }        }        if(subPool != null)            subPool.UnSpawn(go);    }    // 回收所有    public void UnSpawnAll()    {        if (_pools == null) return;        foreach (var subPool in _pools.Values)        {            subPool.UnSpawnAll();        }    }    // 创建新子池子    void RegistreNewPool(string name)    {        // 获取预设        string prefab = "";        if (string.IsNullOrEmpty(ResourceDir))            prefab = name;        else            prefab = ResourceDir + "/"+name;        // 加载预设        GameObject go = Resources.Load<GameObject>(prefab);        // 创建新池子        SubPool pool = new SubPool(transform,go);        _pools.Add(pool.Name,pool);    }}

SubPool.cs 子对象池的实现

using System.Collections.Generic;using UnityEngine;public class SubPool{    // 对象池管理    private Transform _parent;    // 预设    private GameObject _prefab;    // 池子    private List<GameObject> _objects = new List<GameObject>();    // 标识    public string Name    {        get { return _prefab.name; }    }    // 构造    public SubPool(Transform parent, GameObject prefab)    {        this._parent = parent;        this._prefab = prefab;    }    // 从池子中取对象    public GameObject Spawn()    {        GameObject go = null;        // 遍历池子,看是否存在未被使用的对象        foreach (GameObject obj in _objects)        {            if (!obj.activeSelf)            {                go = obj;                break;            }        }        // 如果池子中不存在未被使用的就需要根据prefab实例化一个GameObject出来        // 并将新的对象加入到池子当中        if (go == null)        {            go = UnityEngine.Object.Instantiate(_prefab);            go.transform.parent = _parent;            _objects.Add(go);        }        // 激活对象,并通过该对象发送消息        go.SetActive(true);        go.SendMessage("OnSpawn",SendMessageOptions.DontRequireReceiver);   // 取出实例之后可能需要做一些操作,比如有些Player,可能有默认动画之类的        return go;    }    // 回收对象    public void UnSpawn(GameObject go)    {        // 只回收池子中存在的对象        if (Contains(go))        {            go.SendMessage("OnUnspawn", SendMessageOptions.DontRequireReceiver); // 回收对象的时候需要设置 对象的属性至初始值            go.SetActive(false);                  }    }    // 回收所有对象    public void UnSpawnAll()    {        if (_objects == null) return;        // 只处理池子中所有标识为启用的对象        foreach (GameObject obj in _objects)        {            if(obj.activeSelf)                UnSpawn(obj);        }    }    public bool Contains(GameObject go)    {       return _objects.Contains(go);    }}

接口 IReusable.cs

using System.Collections;using System.Collections.Generic;using UnityEngine;public interface IReusable{    // 当取出时调用    void OnSpawn();   // 根据子对象池中设置的消息通知 每一个Spawn出来的对象上须包含这样的函数用来接收消息    // 当回收时调用    void OnUnspawn();}

可复用对象

using System;using System.Collections.Generic;using System.Text;using UnityEngine;// 可重用的抽象对象类,由其子类来实现方法public abstract class ReusableObject : MonoBehaviour, IReusable{    public abstract void OnSpawn();         // 子对象池Spawn出来的对象 都是需要继承自MonoBehavior的 需要使用Update Awake等函数    public abstract void OnUnspawn();}
原创粉丝点击