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;
    }
}

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