unity遊戲物件池
阿新 • • 發佈:2018-12-13
簡單實現一個遊戲物件池:
物件池的型別,同時也是預設體的名稱:
/**
* 專案名稱:
* 指令碼描述:
* 版本:
* 日期:#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;
}
}