Unity3D 构建对象池

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
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值