Unity3d对象池
Posted huwenya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3d对象池相关的知识,希望对你有一定的参考价值。
Singleton.cs
1
2
3
4
5
6
7
8
9
10
11
12
13using UnityEngine;
/// <summary>
/// 单例模版类
/// </summary>
public class Singleton<T> where T : new() {
private static readonly T instance = new T();
public static T Instance{
get{
return instance;
}
}
}
MonoSingleton.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23using UnityEngine;
/// <summary>
/// 组建单例模版
/// </summary>
public class MonoSingleten<T> : MonoBehaviour where T : MonoBehaviour{
private static T instance;
public static T Instance{
get{
if (instance == null){
GameObject go = new GameObject(typeof(T).Name);
instance = go.AddComponent<T>();
}
return instance;
}
set {
instance = value;
}
}
protected virtual void Awake(){
Instance = this as T;
}
}
IReusable.cs
1
2
3
4
5
6
7
8
9
10using UnityEngine;
/// <summary>
/// 对象池接口
/// </summary>
public interface IReusable{
//对象从对象池实例化的回调
void OnSpawned();
//对象返回对象池后的回调
void OnUnSpawned();
}
PrefabType.cs
1
2
3
4
5public enum PrefabType{
None = 0,
Effects = 1,
Roles = 2,
}
ResourcesPath.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21using UnityEngine;
/// <summary>
/// 资源路径
/// </summary>
public class ResourcesPath {
public const string prefabRoles = "Prefabs/Roles/";
public const string prefabEffects = "Prefabs/Effects/";
public static string GetPath(PrefabType type, string name){
string path = string.Empty;
switch(type){
case PrefabType.Effects:
path = ResourcesPath.prefabEffects + name;
break;
case PrefabType.Roles:
path = ResourcesPath.prefabRoles + name;
break;
}
return path;
}
}
ResourceFactory.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 资源工厂
/// </summary>
public class ResourceFactory : Singleton<ResourceFactory> {
/// <summary>
/// 加载资源
/// </summary>
/// <returns>The load.</returns>
/// <param name="path">Path.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public T Load<T>(string path) where T : Object{
T res = Resources.Load<T>(path);
return res;
}
}
ObjectPoolMananger.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 对象池管理器
/// </summary>
public class ObjectPoolMananger : MonoSingleten<ObjectPoolMananger> {
private Dictionary<string, ObjectPool> mPools = new Dictionary<string, ObjectPool>();
//从对象池取出对象
public GameObject Spawn(PrefabType type, string name, Vector3 pos = default(Vector3), Quaternion rotation = default(Quaternion), Transform parent = null){
ObjectPool pool = null;
if (!mPools.ContainsKey(name)){
//创建对象池
RegisterPoll(type, name);
}
pool = mPools[name];
//从对象池中取出一个物体
GameObject obj = pool.Spawn();
obj.transform.SetParent(parent);
obj.transform.localPosition = pos;
obj.transform.localRotation = rotation;
return obj;
}
/// <summary>
/// 对象池回收物体
/// </summary>
/// <param name="obj">Object.</param>
public void UnSpawn(GameObject obj){
foreach(ObjectPool pool in mPools.Values){
if (pool.Contains(obj)){
pool.UnSpawn(obj);
return ;
}
}
Destroy(obj);
}
/// <summary>
/// 回收所有物体
/// </summary>
public void UnSpwanAll(){
foreach(ObjectPool pool in mPools.Values){
pool.UnSpawnAll();
}
}
private void RegisterPoll(PrefabType type, string name){
string path = ResourcesPath.GetPath(type, name);
GameObject prefab = ResourceFactory.Instance.Load<GameObject>(path);
ObjectPool pool = new ObjectPool(prefab);
mPools.Add(name, pool);
}
}
ObjectPool.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 对象池类
/// </summary>
public class ObjectPool{
//预制体
private GameObject mPrefab;
//对象池
private List<GameObject> objectlist = new List<GameObject>();
//构造方法
public ObjectPool(GameObject prefab){
this.mPrefab = prefab;
}
/// <summary>
/// 取出物体
/// </summary>
/// <returns>The spawn.</returns>
public GameObject Spawn(){
GameObject obj = null;
for (int i = 0; i < objectlist.Count; i++){
if (!objectlist[i].activeSelf){//如果有物体隐藏
obj = objectlist[i];
break;
}
}
if (obj == null){
obj = GameObject.Instantiate(mPrefab);
objectlist.Add(obj);
}
obj.SetActive(true);
//获取对象池接口
IReusable reusable = obj.GetComponent<IReusable>();
if (reusable != null){
reusable.OnSpawned();
}
return obj;
}
/// <summary>
/// 回收物体
/// </summary>
/// <param name="obj">Object.</param>
public void UnSpawn(GameObject obj){
obj.SetActive(false);
IReusable reusable = obj.GetComponent<IReusable>();
if (reusable != null){
reusable.OnUnSpawned();
}
}
public void UnSpawnAll() {
foreach (GameObject obj in objectlist){
obj.SetActive(false);
IReusable reusable = obj.GetComponent<IReusable>();
if (reusable != null){
reusable.OnUnSpawned();
}
}
}
/// <summary>
/// 判断物体是否存在
/// </summary>
/// <returns>The contains.</returns>
/// <param name="obj">Object.</param>
public bool Contains(GameObject obj){
return objectlist.Contains(obj);
}
}
DestoryObjectPool.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 对象池销毁
/// </summary>
public class DestoryObjectPool : MonoBehaviour, IReusable {
public float mDestoryTime = 0.1f;
public void OnSpawned()
{
Invoke("UnSpawn", mDestoryTime);
}
public void OnUnSpawned()
{
}
private void UnSpawn(){
ObjectPoolMananger.Instance.UnSpawn(gameObject);
}
}
以上是关于Unity3d对象池的主要内容,如果未能解决你的问题,请参考以下文章