예제 #1
0
        public GameObject SpawnWeighted(Vector3 position, Quaternion rotation, params string[] ValidKeys)
        {
            int ChooseIndex(float[] probs)
            {
                float total = 0;

                foreach (float elem in probs)
                {
                    total += elem;
                }

                float randomPoint = Random.value * total;

                for (int i = 0; i < probs.Length; i++)
                {
                    if (randomPoint < probs[i])
                    {
                        return(i);
                    }
                    else
                    {
                        randomPoint -= probs[i];
                    }
                }
                return(probs.Length - 1);
            }

            RecycleBin[] validBins = runtimeRecycleBins.Where((KeyValuePair <string, RecycleBin> recycleBinItem)
                                                              => ValidKeys.Any((string key) => key.Equals(recycleBinItem.Key))).
                                     Select((KeyValuePair <string, RecycleBin> recycleBinItem) => recycleBinItem.Value).ToArray();

            if (validBins == null || validBins.Length <= 0)
            {
                Debug.LogError($"[{GetType().Name}] No Valid ObjectPool found with the given keys.");
                return(null);
            }

            int[] priorities  = validBins.Select((RecycleBin bb) => bb.Priority).ToArray();
            int   total_value = priorities.Sum();

            float[] probabilities = priorities.Select((int priority) => (priority / (float)total_value)).ToArray();

            RecycleBin selected_bin = validBins[ChooseIndex(probabilities)];

            GameObject clone = selected_bin.Spawn(position, rotation);

            if (clone != null)
            {
                int _id = clone.GetInstanceID();

                if (!ObjectPoolData.ContainsKey(_id))
                {
                    ObjectPoolData.Add(_id, selected_bin.Label);
                }
            }

            return(clone);
        }
예제 #2
0
        public void CreateObjectPool(GameObject[] prefabs, string objectPoolKey, int preallocateCount = 0, Transform parent = null,
                                     bool forcePoolParent = true)
        {
            if (!ObjectPoolExists(objectPoolKey))
            {
                RecycleBin recycleBin = new RecycleBin(objectPoolKey, prefabs, preallocateCount, parent, forcePoolParent);

                if (preallocateCount > 0)
                {
                    StartCoroutine(recycleBin.Allocate());
                }

                runtimeRecycleBins.Add(objectPoolKey, recycleBin);
            }
            else
            {
                Debug.LogError($"[{GetType().Name}] Can't create object pool: the key already exists");
            }
        }
예제 #3
0
        private IEnumerator I_LoadDefinition(PoolDefinition definition)
        {
            if (definition != null && definition.PoolData.Length > 0)
            {
                RecycleBinData[] poolData = definition.PoolData;
                Debug.Log($"[{GetType().Name}] Load PoolDefinition Started");

                List <RecycleBin> tmp_recycleBins = new List <RecycleBin>();

                for (int i = 0; i < poolData.Length; i++)
                {
                    var current_data = poolData[i];
                    if (string.IsNullOrEmpty(current_data.Label))
                    {
                        Debug.LogWarning($"[{GetType().Name}] Pool With null label detected at position {i}. Ignoring...");
                        continue;
                    }

                    if (runtimeRecycleBins.ContainsKey(current_data.Label))
                    {
                        Debug.LogWarning($"[{GetType().Name}] A Pool already Exists with label '{current_data.Label}'. Ignoring...'");
                        continue;
                    }

                    RecycleBin current = null;

                    switch (current_data.ReferenceType)
                    {
                    case PoolReferenceType.PREFAB:
                        current = new RecycleBin(current_data.Label, current_data.Prefabs,
                                                 current_data.PreallocateCount, null, current_data.UsePoolParent, current_data.Priority);
                        break;

#if ADDRESSABLES_INSTALLED
                    case PoolReferenceType.ASSET_REFERENCE:
                        current = new RecycleBin(current_data.Label, current_data.AssetReference, current_data.PreallocateCount,
                                                 null, current_data.UsePoolParent, current_data.Priority);
                        break;

                    case PoolReferenceType.LABEL_REFERENCE:
                        current = new RecycleBin(current_data.Label, current_data.AssetLabelReference,
                                                 current_data.PreallocateCount, null, current_data.UsePoolParent, current_data.Priority);
                        break;
#endif
                    default: goto case PoolReferenceType.PREFAB;
                    }

                    runtimeRecycleBins.Add(current.Label, current);
                    tmp_recycleBins.Add(current);
                }

                for (int i = 0; i < tmp_recycleBins.Count; i++)
                {
                    yield return(tmp_recycleBins[i].Allocate());
                }
                tmp_recycleBins.Clear();
            }
            yield return(new WaitForEndOfFrame());

            Debug.Log($"[{GetType().Name}] Load PoolDefinition finished");
            if (OnPoolDefinitionLoaded != null)
            {
                OnPoolDefinitionLoaded.Invoke();
            }
        }