unity游戏对象池

简单实现一个游戏对象池:

对象池的类型,同时也是预设体的名称:

/**
 * 项目名称:
 * 脚本描述:
 * 版本:
 * 日期:#DATE#
 * 作者:陈超
 * */
public class ObjectType
{
    //预设体的名称
    public const string Bullet = "Bullet";
}

对象池:使用Dictionary存储子对象池

using UnityEngine;
using System.Collections.Generic;

/**
 * 项目名称:
 * 脚本描述:
 * 版本:
 * 日期:#DATE#
 * 作者:陈超
 * */
public class ObjectPool : Singleton<ObjectPool>
{
    private string resourceDir = "Prefabs";
    private Dictionary<string, SubPool> dict = new Dictionary<string, SubPool>();


    //取对象
    public GameObject Spawn(string type)
    {
        if (!dict.ContainsKey(type))
        {
            RegisterNew(type);   //创建一个新池
        }
        return dict[type].Spawn();
    }

    //回收对象
    public void UnSpawn(string type, GameObject obj)
    {
        if (dict.ContainsKey(type))
        {
            if (dict[type].Contains(obj))
            {
                dict[type].UnSpawn(obj);
            }
            else
            {
                Debug.Log("回收对象失败!对象池" + type + "中不含该物体");
            }
        }
        else
        {
            Debug.Log("回收对象失败!不含对应的对象池!");
        }
    }

    public void UnSpawn(GameObject obj)
    {
        foreach (var item in dict.Values)
        {
            if (item.Contains(obj))
            {
                item.UnSpawn(obj);
                return;
            }
        }
        Debug.Log("回收对象失败!对象池中不含该物体");
    }

    public void UnSpawnAll()
    {
        foreach (var item in dict.Values)
        {
            item.UnSpawnAll();
        }
    }

    //创建新的池子
    private void RegisterNew(string type)
    {
        //加载预设
        string path = resourceDir + "/" + type;
        GameObject prefab = Resources.Load<GameObject>(path);

        SubPool pool = new SubPool(transform, prefab);

        dict.Add(type, pool);
    }
}

子对象池:保存一种游戏对象的池子

using UnityEngine;
using System.Collections.Generic;

/**
 * 项目名称:
 * 脚本描述:
 * 版本:
 * 日期:#DATE#
 * 作者:陈超
 * */
public class SubPool
{

    private List<GameObject> list = new List<GameObject>();
    private Transform m_parent;
    private GameObject m_prefab;

    public SubPool(Transform parent, GameObject prefab)
    {
        this.m_parent = parent;
        this.m_prefab = prefab;
    }

    public GameObject Spawn()
    {
        GameObject obj = null;
        foreach (var item in list)
        {
            if (obj.activeSelf)
            {
                obj = item;
                obj.SetActive(false);
                break;
            }
        }

        if (obj == null)
        {
            obj = GameObject.Instantiate(m_prefab, m_parent);
            list.Add(obj);
        }

        //通知物体被创建
        obj.SendMessage("OnSpawn", SendMessageOptions.DontRequireReceiver);
        return obj;
    }

    public void UnSpawn(GameObject obj)
    {
        obj.SetActive(false);
        //通知物体被销毁
        obj.SendMessage("UnSpawn", SendMessageOptions.DontRequireReceiver);
    }

    public void UnSpawnAll()
    {
        foreach (var item in list)
        {
            UnSpawn(item);
        }
    }

    public bool Contains(GameObject obj)
    {
        return list.Contains(obj);
    }
}

接口:约束游戏物体必须实现的接口

/**
 * 项目名称:
 * 脚本描述:
 * 版本:
 * 日期:#DATE#
 * 作者:陈超
 * */
public interface IReusable
{
    //当取出时调用
    void OnSpawn();

    //当回收时调用
    void OnUnspawn();
}

抽象类:从对象池中取物体和回收物体会响应对应事件

using System;
using UnityEngine;

/**
 * 项目名称:
 * 脚本描述:
 * 版本:
 * 日期:#DATE#
 * 作者:陈超
 * */
public abstract class ReusbleObject : MonoBehaviour, IReusable
{
    public abstract void OnSpawn();

    public abstract void OnUnspawn();
}

单例的实现:

using UnityEngine;

/**
 * 项目名称:
 * 脚本描述:
 * 版本:
 * 日期:#DATE#
 * 作者:陈超
 * */
public class Singleton<T> : MonoBehaviour
    where T : MonoBehaviour
{
    public static T Instance;

    protected void Awake()
    {
        Instance = this as T;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章