示例#1
0
    // ReSharper restore InconsistentNaming

    public PoolBossItem Clone()
    {
        var clone = new PoolBossItem
        {
            prefabSource = prefabSource,
            prefabTransform = prefabTransform,
            instancesToPreload = instancesToPreload,
            isExpanded = isExpanded,
            logMessages = logMessages,
            allowInstantiateMore = allowInstantiateMore,
            itemHardLimit = itemHardLimit,
            allowRecycle = allowRecycle,
            categoryName = categoryName,
            delayNavMeshEnableByFrames = delayNavMeshEnableByFrames
        };

#if ADDRESSABLES_ENABLED
        if (prefabAddressable.RuntimeKeyIsValid())
        {
            clone.prefabAddressable = new AssetReference(prefabAddressable.RuntimeKey.ToString());
        }
#endif

        return clone;
    }
示例#2
0
	// ReSharper disable once MemberCanBeMadeStatic.Local
	private void CreatePoolItemClones(PoolBossItem item, bool isDuringAwake)
	{
		if (!isDuringAwake)
			Instance.poolItems.Add(item);
		
		if (item.instancesToPreload <= 0) return;

		switch (item.prefabSource)
		{
			case PrefabSource.Prefab:
				if (item.prefabTransform == null)
				{
					if (isDuringAwake)
					{
						Debug.LogError(
							$"You have an item in Pool Boss with no prefab assigned in category: {item.categoryName}");
					}
					else
					{
						Debug.LogError("You are attempting to add a Pool Boss Item with no prefab assigned.");
					}
					return;
				}

				FillItemPool(item, item.prefabTransform);

				return;
#if ADDRESSABLES_ENABLED
			case PrefabSource.Addressable:
				if (!PoolAddressableOptimizer.IsAddressableValid(item.prefabAddressable))
				{
					if (isDuringAwake)
					{
						Debug.LogError("You have an item in Pool Boss with no prefab assigned in category: " + item.categoryName);
					}
					else
					{
						Debug.LogError("You are attempting to add a Pool Boss Item with no prefab assigned.");
					}
					return;
				}

				StartCoroutine(PoolAddressableOptimizer.LoadOrReturnTransformAsset(item, FillItemPool, AddressableFailedLoad));

				return;
#endif
		}
	}
示例#3
0
	/// <summary>
	/// This method allows you to add a new Pool Item at runtime.
	/// </summary>
	/// <param name="itemTrans">The Transform of the item.</param>
	/// <param name="preloadInstances">The number of instances to preload.</param>
	/// <param name="canInstantiateMore">Can instantiate more or not</param>
	/// <param name="hardLimit">Item Hard Limit</param>
	/// <param name="logMsgs">Log messages during spawn and despawn.</param>
	/// <param name="catName">Category name</param>
	public static void CreateNewPoolItem(Transform itemTrans, int preloadInstances, bool canInstantiateMore,
										 int hardLimit, bool logMsgs, string catName) {
		var newItem = new PoolBossItem() {
			prefabTransform = itemTrans,
			instancesToPreload = preloadInstances,
			allowInstantiateMore = canInstantiateMore,
			itemHardLimit = hardLimit,
			isExpanded = true,
			logMessages = logMsgs,
			categoryName = catName
		};
		
		if (string.IsNullOrEmpty(catName)) {
			newItem.categoryName = Instance._categories[0].CatName;
		}
		
		Instance.CreatePoolItemClones(newItem, false);
	}
示例#4
0
	private void FillItemPool(PoolBossItem item, Transform transformTemplate)
	{
		var itemName = GetPrefabName(transformTemplate); // calling this here will add the PoolableInfo script to the prefab, so all clones will get it.
		if (PoolItemsByName.ContainsKey(itemName))
		{
			Debug.LogError($"You have more than one instance of '{itemName}' in Pool Boss. Skipping the second instance.");
			return;
		}

		var itemClones = new List<Transform>();

		var navAgent = transformTemplate.GetComponent<NavMeshAgent>();
		var hasAgent = navAgent != null;

		for (var i = 0; i < item.instancesToPreload; i++)
		{
			var createdObjTransform = InstantiateForPool(transformTemplate, i + 1);
			itemClones.Add(createdObjTransform);
		}

		var instanceList = new PoolItemInstanceList(itemClones)
		{
			LogMessages = item.logMessages,
			AllowInstantiateMore = item.allowInstantiateMore,
			SourceTrans = transformTemplate,
			ItemHardLimit = item.itemHardLimit,
			AllowRecycle = item.allowRecycle,
			EnableNavMeshAgent = hasAgent && item.enableNavMeshAgentOnSpawn,
			NavMeshAgentFrameDelay = item.delayNavMeshEnableByFrames,
			CategoryName = item.categoryName
		};

		if (Instance._categories.Find(delegate (PoolBossCategory x) { return x.CatName == item.categoryName; }) == null)
		{
			Instance._categories.Add(new PoolBossCategory()
			{
				CatName = item.categoryName,
				IsExpanded = true,
				IsEditing = false
			});
		}

		PoolItemsByName.Add(itemName, instanceList);
	}
示例#5
0
	private void ContinueInit()
	{
		if (_isReady || Time.frameCount <= _lastFramInitContinued) {
			return;
		}

		_lastFramInitContinued = Time.frameCount;

		var itemCountToStopAt = Instance.poolItems.Count;
		if (Instance.framesForInit != 1) {
			var framesInitSoFar = Time.frameCount - _initFrameStart + 1;
			itemCountToStopAt = (int)Math.Max(framesInitSoFar * _itemsToInitPerFrame, 0);
		}

		if (logMessages) {
			Debug.Log(
				$"Pool Boss initializing: frame #: {Time.frameCount} - creating items: {(_itemsInited + 1)} - {itemCountToStopAt}");
		}

		PoolBossItem item = null;

		// ReSharper disable once ForCanBeConvertedToForeach
		for (var p = _itemsInited; p < itemCountToStopAt; p++) {
			item = Instance.poolItems[p];

			Instance.CreatePoolItemClones(item, true);
			_itemsInited++;
		}

		if (itemCountToStopAt != Instance.poolItems.Count) {
			return;
		}

		if (logMessages) {
			Debug.Log($"Pool Boss done initializing in frame #: {Time.frameCount}");
		}

		_isReady = true;
	}
        private static readonly object _syncRoot = new object(); // to lock below

        /// <summary>
        /// Start Coroutine when calling this, passing in success and failure action delegates.
        /// </summary>
        /// <param name="addressable"></param>
        /// <param name="successAction"></param>
        /// <param name="failureAction"></param>
        /// <returns></returns>
        public static IEnumerator LoadOrReturnTransformAsset(PoolBossItem poolItem, System.Action <PoolBossItem, Transform> successAction, System.Action failureAction)
        {
            var addressable = poolItem.prefabAddressable;

            if (!IsAddressableValid(addressable))
            {
                if (failureAction != null)
                {
                    failureAction();
                }
                yield break;
            }

            var addressableId = GetAddressableId(addressable);

            AsyncOperationHandle <GameObject> loadHandle;
            GameObject gameObjectReference;
            var        shouldReleaseLoadedAssetNow = false;

            if (AddressableTasksByAddressibleId.ContainsKey(addressableId))
            {
                loadHandle          = AddressableTasksByAddressibleId[addressableId].AssetHandle;
                gameObjectReference = loadHandle.Result;
            }
            else
            {
                loadHandle = addressable.LoadAssetAsync <GameObject>();

                while (!loadHandle.IsDone)
                {
                    yield return(PoolBoss.EndOfFrameDelay);
                }

                gameObjectReference = loadHandle.Result;

                if (gameObjectReference == null || loadHandle.Status != AsyncOperationStatus.Succeeded)
                {
                    var errorText = "";
                    if (loadHandle.OperationException != null)
                    {
                        errorText = " Exception: " + loadHandle.OperationException.Message;
                    }
                    Debug.LogError("Addressable file for could not be located." + errorText);

                    if (failureAction != null)
                    {
                        failureAction();
                    }
                    yield break;
                }

                lock (_syncRoot)
                {
                    if (!AddressableTasksByAddressibleId.ContainsKey(addressableId))
                    {
                        AddressableTasksByAddressibleId.Add(addressableId, new AddressableTracker <GameObject>(loadHandle));
                    }
                    else
                    {
                        // race condition reached. Another load finished before this one. Throw this away and use the other, to release memory.
                        shouldReleaseLoadedAssetNow = true;
                        gameObjectReference         = AddressableTasksByAddressibleId[addressableId].AssetHandle.Result;
                    }
                }
            }

            if (shouldReleaseLoadedAssetNow)
            {
                Addressables.Release(loadHandle);
            }


            if (successAction != null)
            {
                successAction(poolItem, gameObjectReference.transform);
            }
        }