• Unity 3D 简易对象池


    • 依赖于UniTask(访问Github)
    • 依赖于Addressable资源管理(通过UPM安装)
    using Cysharp.Threading.Tasks;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AddressableAssets;
    using UnityEngine.ResourceManagement.AsyncOperations;
    
    
    namespace EasyAVG
    {
    
        public class Pool
        {
    
            public Action<GameObject> OnGet { get; set; } = defaultGet;
            public Action<GameObject> OnSet { get; set; } = defaultSet;
            public Action<GameObject> OnDestroy { get; set; } = defaultDestroy;
    
            public Action<GameObject> OnCreate { get; set; } = null;
    
            public int MaxCount { get; set; } = int.MaxValue;
    
            public int MinCount { get; set; } = 0;
    
            public string Location { get; set; } = null;
    
    
    
    
    
            private Queue<GameObject> queue = new Queue<GameObject>();
    
    
            static readonly Action<GameObject> defaultGet = (x) =>
                {
                    x.SetActive(true);
                }
            , defaultSet = (x) =>
            {
                x.SetActive(false);
            }
            , defaultDestroy = (x) =>
            {
                GameObject.Destroy(x);
            };
    
    
    
            internal bool _destroyed = false;
            private IEnumerator PoolThread()
            {
    
                //cacheHandle = Addressables.LoadAssetAsync(Location);
                //yield return cacheHandle;
                while (true)
                {
                    if (_destroyed)
                    {
                        yield break;
                    }
                    if (MinCount > MaxCount) throw new InvalidOperationException($"Please keep MaxCount>MinCount . CurrentMin{MinCount}>CurreentMax{MaxCount}");
                    if (queue.Count < MinCount)
                    {
    
                        var handle = Addressables.InstantiateAsync(Location);
                        yield return handle;
                        OnCreate?.Invoke(handle.Result);
                        queue.Enqueue(handle.Result);
                    }
                    if (queue.Count > MaxCount)
                    {
                        OnDestroy?.Invoke(queue.Dequeue());
                    }
                    yield return null;
    
                }
    
            }
            internal void InitPool()
            {
                PoolManager.Instance.StartCoroutine(PoolThread());
            }
    
    
            public async UniTask<GameObject> Get()
            {
                if (queue.Count == 0)
                {
                    var handle = Addressables.InstantiateAsync(Location);
                    await handle;
                    OnCreate?.Invoke(handle.Result);
                    OnGet?.Invoke(handle.Result);
                    return handle.Result;
                }
                await UniTask.CompletedTask;
                var item = queue.Dequeue();
                OnGet?.Invoke(item);
                return item;
            }
            public GameObject GetSync()
            {
                if (queue.Count == 0)
                {
                    var handle = Addressables.InstantiateAsync(Location);
                    OnCreate?.Invoke(handle.Result);
                    OnGet?.Invoke(handle.Result);
                    return handle.Result;
                }
                var item = queue.Dequeue();
                OnGet?.Invoke(item);
                return item;
            }
    
            public void Set(GameObject item)
            {
                if (queue.Count >= MaxCount)
                {
                    OnSet?.Invoke(item);
                    OnDestroy?.Invoke(item);
                    return;
                }
                else
                {
                    OnSet?.Invoke(item);
                    queue.Enqueue(item);
                }
            }
    
        }
    }
    
    • 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
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    using Cysharp.Threading.Tasks;
    using EasyAVG;
    using System;
    using System.Collections.Generic;
    using UnityEngine;
    
    namespace EasyAVG
    {
    
        public class PoolManager :MonoSingleton<PoolManager>
        {
        
    
            void OnDestroy()
            {
                foreach (var kvp in pools)
                {
                    kvp.Value._destroyed = true;
                }
                pools.Clear();
            }
    
        
    
    
    
            private readonly Dictionary<string, Pool> pools = new Dictionary<string, Pool>();
    
    
            /// 
            /// 创建对象池
            /// 
            /// 
            /// 
            /// 
            /// 
            public void CreatePool(string key, string location, int minCount = 0, int maxCount = int.MaxValue
             )
            {
                if (pools.ContainsKey(key)) return;
                Pool pool = new Pool();
    
                pool.Location = location;
                pool.MinCount = minCount;
                pool.MaxCount = maxCount;
                pools.Add(key, pool);
    
                pool.InitPool();
            }
    
    
            /// 
            /// 获取对象池
            /// 
            /// 
            /// 
            public Pool GetPool(string key)
            {
                if (!pools.ContainsKey(key)) return null;
                return pools[key];
            }
    
    
            /// 
            /// 销毁对象池
            /// 
            /// 
            /// 
            /// 
            public void DestroyPool(string key, bool exThrow = false)
            {
                if (!pools.ContainsKey(key))
                {
                    if (exThrow)
                        throw new NullReferenceException("Destroying non-existent pool is not allowed");
                    else return;
                }
                pools[key]._destroyed = true;
                pools.Remove(key);
            }
    
    
            /// 
            /// 异步获取对象
            /// 
            /// 
            /// 
            /// 
            public UniTask<GameObject> GetAsync(string key)
            {
                var pool = GetPool(key) ?? throw new InvalidOperationException("Please get after create pool");
                return pool.Get();
            }
    
            /// 
            /// 同步获取对象
            /// 
            /// 
            /// 
            /// 
            public GameObject GetSync(string key)
            {
                var pool = GetPool(key) ?? throw new InvalidOperationException("Please get after create pool");
                return pool.GetSync();
            }
    
            /// 
            /// 放回对象
            /// 
            /// 
            /// 
            /// 
            public void Recycle(string key, GameObject obj)
            {
                var pool = GetPool(key) ?? throw new InvalidOperationException("Please set after create pool");
                pool.Set(obj);
            }
    
            /// 
            /// 异步获取组件
            /// 
            /// 
            /// 
            /// 
            public async UniTask<T> GetComponentAsync<T>(string key) where T : Component
            {
                var pool = GetPool(key);
                return (await pool.Get()).GetComponent<T>();
            }
    
            /// 
            /// 同步获取组件
            /// 
            /// 
            /// 
            /// 
            public T GetComponentSync<T>(string key) where T : Component
            {
                var pool = GetPool(key);
                return pool.GetSync().GetComponent<T>();
            }
    
            /// 
            /// 同步回收组件
            /// 
            /// 
            /// 
            /// 
            public void RecycleComponent<T>(string key, T com) where T : Component
            {
                var pool = GetPool(key);
                pool.Set(com.gameObject);
            }
        }
    }
    
    • 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
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
  • 相关阅读:
    毫米波传感器原理介绍:测距
    国际工程承包与管理系统试卷
    安全巡检管理系统如何使用
    基于openai api构建assistant
    大图书馆 #6 开源书单 1.0
    程序员追星 - Gerald Jay Sussman
    可见性检测-unity掌握常见的可见性检测算法实现原理
    文字轮播与图片轮播?CSS 不在话下
    MySQL 核心模块揭秘 | 15 期 | 事务模块小结
    CPD:使用restAPI和cpd-cli命令创建DMC实例
  • 原文地址:https://blog.csdn.net/qq_46273241/article/details/133241236