Unity对象池PoolManager功能

对象池的优点有很多博主以及大神都说到,优化了内存,解决了大量的内存消耗..

对象池类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 对象池类
/// </summary>
public class PoolManager
{
    //单例
    private static PoolManager instance;

    private PoolManager ()
    {

    }

    public static PoolManager Instance {
        get {
            if (instance == null) {
                instance = new PoolManager ();
            }
            return instance;
        }
    }

    //存储各类型的对象池的集合
    Dictionary<string,Subpool> poolDic = new Dictionary<string, Subpool> ();

    /// <summary>
    /// 添加对象池的方法
    /// </summary>
    /// <param name="name">Name.</param>
    void Register (string name)
    {
        GameObject obj = Resources.Load (name)as GameObject;
        Subpool subpool = new Subpool (obj);
        poolDic.Add (name, subpool);
    }

    /// <summary>
    /// 获取对象池中游戏对象
    /// </summary>
    /// <param name="name">Name.</param>
    public GameObject Spawn (string name)
    {
        if (!poolDic.ContainsKey (name)) {
            Register (name);
        }
        Subpool subpool = poolDic [name];
        return subpool.SubPoolSpawn ();
    }

    /// <summary>
    /// 回收游戏对象
    /// </summary>
    /// <param name="obj">Object.</param>
    public void UnSpawn (GameObject obj)
    {
        foreach (Subpool item in poolDic.Values) {
            if (item.SubPoolContains (obj)) {
                item.SubPoolUnSpawn (obj);
                break;
            }
        }
    }

    /// <summary>
    /// 清除游戏对象
    /// </summary>
    public void ClearPool ()
    {
        poolDic.Clear ();
    }
}

 

   管理相同类型的对象:

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 管理相同类型的对象
/// </summary>
public class Subpool
{
    List<GameObject> pool = new List<GameObject> ();
    //要创建的游戏游戏对象预设体
    private GameObject prefab;

    //创建的预设体名字
    public Subpool (GameObject obj)
    {
        prefab = obj;
    }
    //返回预设体的名字,定义的预设体的名字与对象池一致,方便池子管理类找对应的池子
    public string name {
        get {
            return prefab.name;
        }
    }

    /// <summary>
    /// 从池子中拿对象
    /// </summary>
    /// <returns>The pool spawn.</returns>
    public GameObject SubPoolSpawn ()
    {
        GameObject obj = null;
        //遍历对象池中是否有可以使用的对象
        //有,就激活拿出来使用
        foreach (GameObject item in pool) {
            if (item.activeSelf == false) {
                obj = item;
                break;
            }
        }
        if (obj == null) {
            obj = GameObject.Instantiate (prefab)as GameObject;
            pool.Add (obj);
        }
        obj.SetActive (true);

        //通过子类实例化接口对象,子类的脚本组件继承并实现了接口中的方法
        //control里面存的是该子类实现的方法,如果要生成一些特效,或者其他游戏行为,那么就可以继承IControl,通过它来进行调用


        IControl control = obj.GetComponent <IControl> ();
        if (control != null) {
            control.Spawn ();
        }

        return obj;
    }

    /// <summary>
    /// 回收游戏对象
    /// </summary>
    /// <param name="obj">Object.</param>
    public void SubPoolUnSpawn (GameObject obj)
    {
        IControl control = obj.GetComponent <IControl> ();
        if (control != null) {
            control.UnSpawn ();
        }
        obj.SetActive (false);
    }

    /// <summary>
    /// 回收所有的游戏对象
    /// </summary>
    public void SubPoolUnSpawnAll ()
    {
        //回收用于处于激活状态的游戏对象
        foreach (GameObject item in pool) {
            if (item.activeSelf) {
                SubPoolUnSpawn (item);
            }
        }
    }

    /// <summary>
    /// 检查某个游戏对象是否在对象池中
    /// </summary>
    /// <returns><c>true</c>, if pool contains was subed, <c>false</c> otherwise.</returns>
    /// <param name="obj">Object.</param>
    public bool SubPoolContains (GameObject obj)
    {
        return pool.Contains (obj);
    }

}

 

  取对象和回收对象的接口:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface IControl
{

    //从对象池中取对象的方法
    void Spawn () ;


    //销毁对象到对象池的方法
    void UnSpawn () ;

}

  调用方式Manager:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 生成子弹,挂载在Manager上
/// </summary>
public class CreatBulletScript : MonoBehaviour
{
    public static CreatBulletScript Instance;

    int count = 0;

    void Awake ()
    {
        Instance = this;
    }

    void SpawnBullet ()
    {
        GameObject temp = PoolManager.Instance.Spawn ("Bullet");
        temp.transform.SetParent (transform);
        temp.transform.localPosition = Vector3.zero;
        count++;
    }

    /// <summary>
    /// 可以给外部调用
    /// </summary>
    /// <param name="obj">Object.</param>
    public void UnSpawnBullet (GameObject obj)
    {
        PoolManager.Instance.UnSpawn (obj);
        count--;
    }

    void Update ()
    {
        if (Input.GetMouseButtonDown (0)) {
            SpawnBullet ();
        }
    }
}

  生成的子弹:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 挂载在Bullet上
/// </summary>
public class Bullet : MonoBehaviour
{

    float timer = 0;
    /// <summary>
    /// 时间间隔
    /// </summary>
    float timeInterval = 2;

    void Update ()
    {
        timer += Time.deltaTime;
        transform.localPosition += new Vector3 (0, 0, 1);
        if (timer >= timeInterval) {
            CreatBulletScript.Instance.UnSpawnBullet (gameObject);
            timer = 0;
        }
    }
}

  PoolManager.unitypackage.zip Demo下载

 对象池优化版,在Spawn的时候,对它进行赋值操作..

SubPool:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 管理相同类型的对象
/// </summary>
public class Subpool
{
    List<GameObject> pool = new List<GameObject>();
    //要创建的游戏游戏对象预设体
    private GameObject prefab;

    //创建的预设体名字
    public Subpool(GameObject obj)
    {
        prefab = obj;
    }
    //返回预设体的名字,定义的预设体的名字与对象池一致,方便池子管理类找对应的池子
    public string name
    {
        get
        {
            return prefab.name;
        }
    }

    /// <summary>
    /// 从池子中拿对象
    /// </summary>
    /// <returns>The pool spawn.</returns>
    public GameObject SubPoolSpawn(Transform parent, Vector3 position, Quaternion quaternion)
    {
        GameObject obj = null;
        //遍历对象池中是否有可以使用的对象
        //有,就激活拿出来使用
        foreach (GameObject item in pool)
        {
            if (item.activeSelf == false)
            {
                obj = item;
                break;
            }
        }
        if (obj == null)
        {
            obj = GameObject.Instantiate(prefab) as GameObject;
            pool.Add(obj);
        }
        obj.transform.position = position;
        obj.transform.rotation = quaternion;
        obj.transform.SetParent(parent);
        obj.SetActive(true);
        //通过子类实例化接口对象,子类的脚本组件继承并实现了接口中的方法
     //control里面存的是该子类实现的方法,如果要生成一些特效,或者其他游戏行为,那么就可以继承IControl,通过它来进行调用
        IControl control = obj.GetComponent<IControl>();
        if (control != null)
        {
            control.Spawn();
        }

        return obj;
    }

    /// <summary>
    /// 回收游戏对象
    /// </summary>
    /// <param name="obj">Object.</param>
    public void SubPoolUnSpawn(GameObject obj)
    {
        IControl control = obj.GetComponent<IControl>();
        if (control != null)
        {
            control.UnSpawn();
        }
        obj.SetActive(false);
    }

    /// <summary>
    /// 回收所有的游戏对象
    /// </summary>
    public void SubPoolUnSpawnAll()
    {
        //回收用于处于激活状态的游戏对象
        foreach (GameObject item in pool)
        {
            if (item.activeSelf)
            {
                SubPoolUnSpawn(item);
            }
        }
    }

    /// <summary>
    /// 检查某个游戏对象是否在对象池中
    /// </summary>
    /// <returns><c>true</c>, if pool contains was subed, <c>false</c> otherwise.</returns>
    /// <param name="obj">Object.</param>
    public bool SubPoolContains(GameObject obj)
    {
        return pool.Contains(obj);
    }

}

PoolManager:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 对象池类
/// </summary>
public class PoolManager
{
    //单例
    private static PoolManager instance;

    private PoolManager()
    {

    }

    public static PoolManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new PoolManager();
            }
            return instance;
        }
    }

    //存储各类型的对象池的集合
    Dictionary<string, Subpool> poolDic = new Dictionary<string, Subpool>();

    /// <summary>
    /// 添加对象池的方法
    /// </summary>
    /// <param name="name">Name.</param>
    void Register(GameObject _obj)
    {
        GameObject obj = _obj;
        Subpool subpool = new Subpool(obj);
        poolDic.Add(obj.name, subpool);
    }

    /// <summary>
    /// 获取对象池中游戏对象
    /// </summary>
    /// <param name="name">Name.</param>
    public GameObject Spawn(GameObject obj, Transform parent, Vector3 position, Quaternion quaternion)
    {
        if (!poolDic.ContainsKey(obj.name))
        {
            Register(obj);
        }
        Subpool subpool = poolDic[obj.name];
        return subpool.SubPoolSpawn(parent, position, quaternion);
    }

    /// <summary>
    /// 回收游戏对象
    /// </summary>
    /// <param name="obj">Object.</param>
    public void UnSpawn(GameObject obj)
    {
        foreach (Subpool item in poolDic.Values)
        {
            if (item.SubPoolContains(obj))
            {
                item.SubPoolUnSpawn(obj);
                break;
            }
        }
    }

    /// <summary>
    /// 清除游戏对象
    /// </summary>
    public void ClearPool()
    {
        poolDic.Clear();
    }
}

 Bullet中:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 挂载在Bullet上
/// </summary>
public class Bullet : MonoBehaviour, IControl
{
    protected ParticleSystem[] pss;
    float timer = 0;
    /// <summary>
    /// 时间间隔
    /// </summary>
    float timeInterval = 2;
    void Awake()
    {
        pss = transform.GetComponentsInChildren<ParticleSystem>();
    }

    public void Spawn()
    {
        Debug.Log("Spawn");
        PlayEffect();
    }

    public void UnSpawn()
    {
        Debug.Log("UnSpawn");
        ResetEffect();
    }

    void Update()
    {
        timer += Time.deltaTime;
        transform.localPosition += new Vector3(0, 0, 1);
        if (timer >= timeInterval)
        {
            CreatBulletScript.Instance.UnSpawnBullet(gameObject);
            timer = 0;
        }
    }
    /// <summary>
    /// 播放特效
    /// </summary>
    void PlayEffect()
    {
        foreach (var item in pss)
        {
            item.Play();
        }
    }

    /// <summary>
    /// 结束特效
    /// </summary>
    void ResetEffect()
    {
        foreach (var item in pss)
        {
            item.Stop();
        }
    }
}

 GitHub 链接 : https://github.com/KinJin-Ristina/PoolManager 

posted @ 2018-10-16 14:26  不够自律的人  阅读(1384)  评论(0编辑  收藏  举报