Unity3D-对象池

Posted 穿迷彩服的鲨鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D-对象池相关的知识,希望对你有一定的参考价值。


前言

简单的写了一个子弹的对象池


提示:以下是本篇文章正文内容,下面案例可供参考

一、准备一个场景

  • 在Hierarchy面板下新建一个Empty,用来挂载脚本

二、新建脚本

1.Pool脚本

代码如下(示例):

/****************************************************
    文件:Pool.cs
	作者:HKZ
    邮箱: 3046916186@qq.com
    日期:2021/12/1 19:52:18
	功能:对象池
*****************************************************/

using System.Collections.Generic;
using UnityEngine;

namespace HKZ

    [System.Serializable]
    public class Pool
    
        [SerializeField]
        private GameObject prefab;
        [SerializeField]
        private int size = 1;
        private Transform parent;

        private Queue<GameObject> queue;

        public GameObject Prefab  get => prefab; 
        public int Size => size;

        public void Initialize(Transform parent)
        
            queue = new Queue<GameObject>();
            this.parent = parent;
            for (int i = 0; i < Size; ++i)
            
                queue.Enqueue(Copy());
            
        

        private GameObject Copy()
        
            var copy = GameObject.Instantiate(Prefab, parent);
            copy.SetActive(false);
            return copy;
        

        private GameObject AvailableObject()
        
            GameObject avaliableObject = null;
            if (queue.Count > 0 && !queue.Peek().activeSelf)
            
                avaliableObject = queue.Dequeue();
            
            else
            
                avaliableObject = Copy();
            
            queue.Enqueue(avaliableObject);
            //avaliableObject.SetActive(true);
            return avaliableObject;
        

        public GameObject PreparedObject()
        
            GameObject preparedObject = AvailableObject();
            
            preparedObject.SetActive(true);

            return preparedObject;
        
        public GameObject PreparedObject(Vector3 position)
        
            GameObject preparedObject = AvailableObject();
            
            preparedObject.SetActive(true);
            preparedObject.transform.position = position;

            return preparedObject;
        
    

2.新建PoolManager脚本

代码如下(示例):

/****************************************************
    文件:PoolManager.cs
	作者:HKZ
    邮箱: 3046916186@qq.com
    日期:2021/12/1 20:14:46
	功能:Nothing
*****************************************************/

using System.Collections.Generic;
using UnityEngine;

namespace HKZ

    public class PoolManager : MonoBehaviour
    
        [SerializeField]
        private Pool[] playerProjectilePools;

        private static Dictionary<GameObject, Pool> dictionary;

        private void Start()
        
            dictionary = new Dictionary<GameObject, Pool>();
            Initialize(playerProjectilePools);
        

        private void Initialize(Pool[] pools)
        
            foreach (var pool in pools)
            
                if (dictionary.ContainsKey(pool.Prefab))
                
                    Debug.LogError("Same prefab in multiple pools!--->Prefab:" + pool.Prefab.name);
                    continue;
                
                dictionary.Add(pool.Prefab, pool);
                Transform poolParent = new GameObject("Pool:" + pool.Prefab.name).transform;
                poolParent.parent = transform;

                pool.Initialize(poolParent);
            
        

        public static GameObject Release(GameObject prefab)
        
            if (!dictionary.ContainsKey(prefab))
            
                Debug.LogError("Pool Manager could not find prefab" + prefab.name);
                return null;
            
            return dictionary[prefab].PreparedObject();
        
        public static GameObject Release(GameObject prefab, Vector3 position)
        
            if (!dictionary.ContainsKey(prefab))
            
                Debug.LogError("Pool Manager could not find prefab" + prefab.name);
                return null;
            
            return dictionary[prefab].PreparedObject(position);
        
       
    


三、把Pool脚本挂载在新建的Empty上

  • 调用PoolManager脚本里的Release函数即可

以上是关于Unity3D-对象池的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D-对象池

Unity3D-对象池

Unity3D-对象池

Unity3D 基于预设(Prefab)的泛型对象池实现

Unity3d对象池

Unity3D 对象池思想 在游戏开发中的运用