1. 程式人生 > >unity遊戲物件池

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