unity3D 开发游戏常常需要构建对象池,特别是中大型端游。下面视频链接告诉你为什么需要构建对象池.点击打开链接
首先介绍一下啊接口
IGoInfo 接口用于外界访问对象的类型,以及调用其回收函数
namespace JumpGame {
public interface IGoInfo {
PrefabType Type { get; }
void Recycle();
}
}
IPool 接口用于外界访问其管理的对象类型,最大数量,初始化对象池,获取对象,回收对象
using UnityEngine;
namespace JumpGame {
public interface IPool {
int MaxCount { get; } // 最大对象数
PrefabType Type { get; } // 对象类型
void Init(int maxCount, PrefabType type); // 初始化对象池
GameObject GetResource(); // 获取对象
void Recycle(GameObject Go); // 回收对象
}
}
下面介绍一些工具类
PathTool 工具类用于保存路径信息
using UnityEngine;
using System.Collections.Generic;
namespace JumpGame {
public enum PrefabType {
Bwood_Left,
Bwood_Middle,
Bwood_Right,
Crocodile,
Drop,
Duck_0,
Duck_1,
Island_Left,
Island_Right,
Water_0,
Water_1
}
public enum SinglePrefabType {
Bg,
Player,
}
public static class PathTool {
private static Dictionary<PrefabType, string> prefabPathDict;
private static Dictionary<SinglePrefabType, string> singlePrefabPathDict;
public static Dictionary<PrefabType, string> PrefabPathDict {
get {
if (prefabPathDict == null) {
prefabPathDict = new Dictionary<PrefabType, string>();
prefabPathDict.Add(PrefabType.Bwood_Left, "Scenes/Bwood_Left");
prefabPathDict.Add(PrefabType.Bwood_Middle, "Scenes/Bwood_Middle");
prefabPathDict.Add(PrefabType.Bwood_Right, "Scenes/Bwood_Right");
prefabPathDict.Add(PrefabType.Crocodile, "Scenes/Crocodile");
prefabPathDict.Add(PrefabType.Drop, "Scenes/Drop");
prefabPathDict.Add(PrefabType.Duck_0, "Scenes/Duck_0");
prefabPathDict.Add(PrefabType.Duck_1, "Scenes/Duck_1");
prefabPathDict.Add(PrefabType.Island_Left, "Scenes/Island_Left");
prefabPathDict.Add(PrefabType.Island_Right, "Scenes/Island_Right");
prefabPathDict.Add(PrefabType.Water_0, "Scenes/Water_0");
prefabPathDict.Add(PrefabType.Water_1, "Scenes/Water_1");
} // end if
return prefabPathDict;
} // end get
} // end
public static Dictionary<SinglePrefabType, string> SinglePrefabPathDict {
get {
if (singlePrefabPathDict == null) {
singlePrefabPathDict = new Dictionary<SinglePrefabType, string>();
singlePrefabPathDict.Add(SinglePrefabType.Bg, "Scenes/Bg");
singlePrefabPathDict.Add(SinglePrefabType.Player, "Scenes/Player");
} // end if
return singlePrefabPathDict;
} // end get
} // end
}
}
PoolConfig 用于配置对象池
using JumpGame;
using System.Collections.Generic;
public class PoolConfig {
private Dictionary<PrefabType, int> infoDict;
public Dictionary<PrefabType, int> InfoDict {
get {
if (infoDict == null) {
infoDict = new Dictionary<PrefabType, int>();
infoDict.Add(PrefabType.Bwood_Left, 10);
infoDict.Add(PrefabType.Bwood_Middle, 10);
infoDict.Add(PrefabType.Bwood_Right, 10);
infoDict.Add(PrefabType.Crocodile, 10);
infoDict.Add(PrefabType.Drop, 10);
infoDict.Add(PrefabType.Duck_0, 10);
infoDict.Add(PrefabType.Duck_1, 10);
infoDict.Add(PrefabType.Island_Left, 10);
infoDict.Add(PrefabType.Island_Right, 10);
infoDict.Add(PrefabType.Water_0, 10);
infoDict.Add(PrefabType.Water_1, 10);
} // end if
return infoDict;
} // end get
} // InfoDict
}
PrefabTool 用于保存已加载的预制体
using UnityEngine;
using System.Collections.Generic;
namespace JumpGame {
public static class PrefabTool {
private static Dictionary<PrefabType, GameObject> prefabDict;
public static Dictionary<PrefabType, GameObject> PrefabDict {
get {
if (prefabDict == null) {
prefabDict = new Dictionary<PrefabType, GameObject>();
} // end if
return prefabDict;
}
} // end
}
}
下面实现一下对象池类
using UnityEngine;
using System.Collections.Generic;
namespace JumpGame {
public class GameObjectPool : MonoBehaviour, IPool {
public int MaxCount { get; private set; }
public PrefabType Type { get; private set; }
private List<GameObject> _GoList = new List<GameObject>();
public void Init(int maxCount, PrefabType type) {
MaxCount = maxCount;
Type = type;
}
public GameObject GetResource() {
GameObject Go = null;
if (_GoList.Count > 0) {
Go = _GoList[0];
_GoList.RemoveAt(0);
} else {
GameObject prefab = null;
if (PrefabTool.PrefabDict.ContainsKey(Type)) {
prefab = PrefabTool.PrefabDict[Type];
} else {
prefab = Resources.Load<GameObject>(PathTool.PrefabPathDict[Type]);
PrefabTool.PrefabDict.Add(Type, prefab);
} // end if
Go = Instantiate(prefab);
switch (Type) { // 这里根据类型添加不同脚本给对象
case PrefabType.Bwood_Left:
Go.AddComponent<Bwood_Left>().Init();
break;
case PrefabType.Bwood_Middle:
Go.AddComponent<Bwood_Middle>().Init();
break;
case PrefabType.Bwood_Right:
Go.AddComponent<Bwood_Right>().Init();
break;
case PrefabType.Crocodile:
Go.AddComponent<Crocodile>().Init();
break;
case PrefabType.Drop:
Go.AddComponent<Drop>().Init();
break;
case PrefabType.Duck_0:
Go.AddComponent<Duck_0>().Init();
break;
case PrefabType.Duck_1:
Go.AddComponent<Duck_1>().Init();
break;
case PrefabType.Island_Left:
Go.AddComponent<Island_Left>().Init();
break;
case PrefabType.Island_Right:
Go.AddComponent<Island_Right>().Init();
break;
case PrefabType.Water_0:
Go.AddComponent<Water_0>().Init();
break;
case PrefabType.Water_1:
Go.AddComponent<Water_1>().Init();
break;
} // end switch
Go.SetActive(false);
Go.transform.SetParent(transform);
Go.transform.localPosition = Vector3.zero;
}// end if
return Go;
}
public void Recycle(GameObject Go) {
if (Go == null) return;
// end if
if (_GoList.Count < MaxCount) {
_GoList.Add(Go);
Go.SetActive(false);
Go.transform.SetParent(transform);
Go.transform.localPosition = Vector3.zero;
} else {
Destroy(Go);
}// end if
}
}
}
创建一个资源管理类管理所有对象池
using UnityEngine;
using System.Collections.Generic;
using JumpGame;
namespace MyManager {
public class ResourcesManager : IManager {
public ManagerStatus mStatus { get; private set; }
// 对象池字典
private Dictionary<PrefabType, IPool> PoolDict;
public void Startup() {
mStatus = ManagerStatus.Initialing;
PoolDict = new Dictionary<PrefabType, IPool>();
PoolConfig config = new PoolConfig();
// 添加对象池
foreach (KeyValuePair<PrefabType, int> info in config.InfoDict) {
PushPoolWithTypeAndMaxCount(info.Key, info.Value);
} // end if
mStatus = ManagerStatus.Started;
} // end Method
/// <summary>
/// 根据对象类型与对象的最大数量添加对象池
/// </summary>
/// <param name="type"> 对象类型 </param>
/// <param name="maxCount"> 对象的最大数量 </param>
private void PushPoolWithTypeAndMaxCount(PrefabType type, int maxCount) {
GameObject Go = new GameObject();
Transform parentTrans = GameObject.Find("RootManager").transform;
Go.name = type.ToString();
IPool pool = Go.AddComponent<GameObjectPool>();
pool.Init(maxCount, type);
PoolDict.Add(type, pool);
Go.transform.SetParent(parentTrans);
}
/// <summary>
/// 根据对象类型获取对象
/// </summary>
/// <param name="type"> 对象类型 </param>
/// <returns></returns>
public GameObject GetResourceWithType(PrefabType type) {
if (PoolDict.ContainsKey(type)) {
return PoolDict[type].GetResource();
} // end if
return null;
} // end Method
/// <summary>
/// 回收游戏物体
/// </summary>
/// <param name="Go"></param>
public void RecylceWithGo(GameObject Go) {
IGoInfo info = Go.GetComponent<IGoInfo>();
if (info == null) return;
if (PoolDict.ContainsKey(info.Type)) {
PoolDict[info.Type].Recycle(Go);
} // end if
} // end Method
} // end Class
}