Пример #1
0
        // ReSharper disable once UnusedMember.Local
        private void Start()
        {
            if (PlayerPrefab == null)
            {
                LevelSettings.LogIfNew("No Player Prefab is assigned to PlayerSpawner. PlayerSpawn disabled.");
                _isDisabled = true;
                return;
            }
            if (RespawnDelay < 0)
            {
                LevelSettings.LogIfNew("Respawn Delay must be a positive number. PlayerSpawn disabled.");
                _isDisabled = true;
                return;
            }

            _nextSpawnTime  = null;
            _playerPosition = spawnPosition;

            var pl = GameObject.Find(PlayerPrefab.name);

            _player = pl == null ? null : pl.transform;

            if (_player == null && PoolBoss.IsReady)
            {
                SpawnPlayer();
            }
        }
    // ReSharper disable once UnusedMember.Local
    void Start()
    {
        var poolNames = new List <string>();

        // ReSharper disable once TooWideLocalVariableScope
        WavePrefabPool poolScript;

        for (var i = 0; i < transform.childCount; i++)
        {
            var pool = transform.GetChild(i);
            if (poolNames.Contains(pool.name))
            {
                LevelSettings.LogIfNew("You have more than one Prefab Pool with the name '" + pool.name + "'. Please fix this before continuing.");
                LevelSettings.IsGameOver = true;
                return;
            }

            poolScript = pool.GetComponent <WavePrefabPool>();
            if (poolScript == null)
            {
                LevelSettings.LogIfNew("The Prefab Pool '" + pool.name + "' has no Prefab Pool script. Please delete it and fix this before continuing.");
                LevelSettings.IsGameOver = true;
                return;
            }

            poolNames.Add(pool.name);
        }
    }
Пример #3
0
    private static void ChangeSpawnerWaveStatus(WaveSyncroPrefabSpawner spawner, int levelNumber, int waveNumber, bool isActivate)
    {
        var statusText = isActivate ? "activate" : "deactivate";

        if (spawner == null)
        {
            LevelSettings.LogIfNew(string.Format("Spawner was NULL. Cannot {0} wave# {1} in level# {2}",
                                                 statusText,
                                                 waveNumber,
                                                 levelNumber));
            return;
        }

        foreach (var wave in spawner.waveSpecs)
        {
            if (wave.SpawnLevelNumber + 1 != levelNumber || wave.SpawnWaveNumber + 1 != waveNumber)
            {
                continue;
            }
            if (LevelSettings.IsLoggingOn)
            {
                Debug.Log(string.Format("Logging '{0}' in spawner '{1}' for wave# {2}, level# {3}.",
                                        statusText,
                                        spawner.name,
                                        waveNumber,
                                        levelNumber));
            }
            wave.enableWave = isActivate;
            return;
        }

        LevelSettings.LogIfNew(string.Format("Could not locate a wave matching wave# {0}, level# {1}, in spawner '{2}'.",
                                             waveNumber, levelNumber, spawner.name));
    }
Пример #4
0
    /// <summary>
    /// This will tell you how many clones of a prefab are already spawned out of Pool Boss. A value of -1 indicates an error
    /// </summary>
    /// <param name="transPrefab">The transform component of the prefab you want the spawned count of.</param>
    public static int PrefabSpawnedCount(Transform transPrefab)
    {
        if (Instance == null)
        {
            // Scene changing, do nothing.
            return(-1);
        }

        if (transPrefab == null)
        {
            LevelSettings.LogIfNew("No Transform passed to SpawnedCountOfPrefab method.");
            return(-1);
        }

        var itemName = GetPrefabName(transPrefab);

        if (!PoolItemsByName.ContainsKey(itemName))
        {
            LevelSettings.LogIfNew("The Transform '" + itemName + "' passed to SpawnedCountOfPrefab is not in Pool Boss. Not despawning.");
            return(-1);
        }

        var spawned = PoolItemsByName[itemName].SpawnedClones.Count;

        return(spawned);
    }
Пример #5
0
    /// <summary>
    /// This method will despawn all spawned instances of the prefab you pass in.
    /// </summary>
    /// <param name="transToDespawn">Transform component of a prefab</param>
    public static void DespawnAllOfPrefab(Transform transToDespawn)
    {
        if (Instance == null)
        {
            // Scene changing, do nothing.
            return;
        }

        if (transToDespawn == null)
        {
            LevelSettings.LogIfNew("No Transform passed to DespawnAllOfPrefab method.");
            return;
        }

        var itemName = GetPrefabName(transToDespawn);

        if (!PoolItemsByName.ContainsKey(itemName))
        {
            LevelSettings.LogIfNew("The Transform '" + itemName + "' passed to DespawnAllOfPrefab is not in Pool Boss. Not despawning.");
            return;
        }

        var spawned = PoolItemsByName[itemName].SpawnedClones;

        var max = spawned.Count;

        while (spawned.Count > 0 && max > 0)
        {
            Despawn(spawned[0]);
            max--;
        }
    }
Пример #6
0
    /// <summary>
    /// Call this method to despawn a prefab using Pool Boss. All the Spawners and Killable use this method.
    /// </summary>
    /// <param name="transToDespawn">Transform to despawn</param>
    public static void Despawn(Transform transToDespawn)
    {
        if (!_isReady)
        {
            LevelSettings.LogIfNew(NotInitError);
            return;
        }

        // ReSharper disable once ConditionIsAlwaysTrueOrFalse
        // ReSharper disable HeuristicUnreachableCode
        if (transToDespawn == null)
        {
            LevelSettings.LogIfNew("No Transform passed to Despawn method.");
            return;
        }
        // ReSharper restore HeuristicUnreachableCode

        if (Instance == null)
        {
            // Scene changing, do nothing.
            return;
        }

        if (!SpawnUtility.IsActive(transToDespawn.gameObject))
        {
            return; // already sent to despawn
        }

        var itemName = GetPrefabName(transToDespawn);

        if (!PoolItemsByName.ContainsKey(itemName))
        {
            if (Instance.autoAddMissingPoolItems)
            {
                CreateMissingPoolItem(transToDespawn, itemName, false);
            }
            else
            {
                LevelSettings.LogIfNew("The Transform '" + itemName + "' passed to Despawn is not in Pool Boss. Not despawning.");
                return;
            }
        }

        transToDespawn.BroadcastMessage(DespawnedMessageName, SendMessageOptions.DontRequireReceiver);

        var cloneList = PoolItemsByName[itemName];

        SetParent(transToDespawn, Trans);

        SpawnUtility.SetActive(transToDespawn.gameObject, false);
        Instance._changes++;

        if (Instance.logMessages || cloneList.LogMessages)
        {
            Debug.Log("Pool Boss despawned '" + itemName + "' at " + Time.time);
        }

        cloneList.SpawnedClones.Remove(transToDespawn);
        cloneList.DespawnedClones.Add(transToDespawn);
    }
        /// <summary>
        /// Modifies a World Variable by name. You can set, add, multiply or subtract the value.
        /// </summary>
        /// <param name='modifier'>Modifier.</param>
        /// <param name='sourceTrans'>Source trans. Optional - this will output in the debug message if the World Variable is not found.</param>
        public static void ModifyPlayerStat(WorldVariableModifier modifier, Transform sourceTrans = null)
        {
            var statName = modifier._statName;

            if (!InGamePlayerStats.ContainsKey(statName))
            {
                LevelSettings.LogIfNew(
                    string.Format(
                        "Transform '{0}' tried to modify a World Variable called '{1}', which was not found in this scene.",
                        sourceTrans == null ? LevelSettings.EmptyValue : sourceTrans.name,
                        statName));

                return;
            }

            var stat = InGamePlayerStats[statName];

            switch (modifier._varTypeToUse)
            {
            case VariableType._integer:
            case VariableType._float:
                stat.ModifyVariable(modifier);
                break;

            default:
                LevelSettings.LogIfNew("Write code for varType: " + modifier._varTypeToUse.ToString());
                break;
            }
        }
 public void CheckForIllegalCustomEvents()
 {
     if (CustomEvent != LevelSettings.NoEventName && !LevelSettings.CustomEventExists(CustomEvent))
     {
         LevelSettings.LogIfNew("Transform '" + name + "' is set up to receive or fire Custom Event '" +
                                CustomEvent + "', which does not exist in Core GameKit.");
     }
 }
Пример #9
0
 private static int NumberOfClones(PoolItemInstanceList instList)
 {
     if (_isReady)
     {
         return(instList.DespawnedClones.Count + instList.SpawnedClones.Count);
     }
     LevelSettings.LogIfNew(NotInitError);
     return(-1);
 }
Пример #10
0
 /// <summary>
 /// Call this method determine if the item name you pass in is set up in Pool Boss.
 /// </summary>
 /// <param name="transName">Item name you want to know is in the Pool or not.</param>
 public static bool PrefabIsInPool(string transName)
 {
     if (_isReady)
     {
         return(PoolItemsByName.ContainsKey(transName));
     }
     LevelSettings.LogIfNew(NotInitError);
     return(false);
 }
Пример #11
0
 /// <summary>
 /// Call this method determine if the item (Transform) you pass in is set up in Pool Boss.
 /// </summary>
 /// <param name="trans">Transform you want to know is in the Pool or not.</param>
 public static bool PrefabIsInPool(Transform trans)
 {
     if (_isReady)
     {
         return(PrefabIsInPool(trans.name));
     }
     LevelSettings.LogIfNew(NotInitError);
     return(false);
 }
 public static void LogIfInvalidWorldVariable(string worldVariableName, Transform trans, string fieldName,
                                              int?levelNum = null, int?waveNum = null, string trigEventName = null)
 {
     if (LevelSettings.IllegalVariableNames.Contains(worldVariableName))
     {
         if (!string.IsNullOrEmpty(trigEventName))
         {
             LevelSettings.LogIfNew(
                 string.Format("The '{0}' field in '{1}' has no Variable assigned for event '{2}'.",
                               fieldName, trans.name, trigEventName));
         }
         else if (levelNum.HasValue && waveNum.HasValue)
         {
             LevelSettings.LogIfNew(
                 string.Format("The '{0}' field in '{1}' has no Variable assigned for Level {2} Wave {3}.",
                               fieldName, trans.name, levelNum.Value + 1, waveNum.Value + 1));
         }
         else
         {
             LevelSettings.LogIfNew(string.Format("The '{0}' field in '{1}' has no Variable assigned.",
                                                  fieldName, trans.name));
         }
     }
     else
     {
         if (!string.IsNullOrEmpty(trigEventName))
         {
             LevelSettings.LogIfNew(
                 string.Format(
                     "The '{0}' field in '{1}' is using an invalid Variable '{2} for event '{3}'. That variable is not in the Scene.",
                     fieldName,
                     trans.name,
                     worldVariableName,
                     trigEventName));
         }
         else if (levelNum.HasValue && waveNum.HasValue)
         {
             LevelSettings.LogIfNew(
                 string.Format(
                     "The '{0}' field in '{1}' is using an invalid Variable '{2}' for Level {3} Wave {4}. That variable is not in the Scene",
                     fieldName, trans.name, worldVariableName, levelNum.Value + 1, waveNum.Value + 1));
         }
         else
         {
             LevelSettings.LogIfNew(
                 string.Format(
                     "The '{0}' field in '{1}' is using an invalid Variable '{2}' That variable is not in the Scene.",
                     fieldName, trans.name, worldVariableName));
         }
     }
 }
Пример #13
0
    // ReSharper disable once UnusedMember.Local
    void Awake()
    {
        _isReady = false;

        PoolItemsByName.Clear();

        for (var p = 0; p < poolItems.Count; p++)
        {
            var item = poolItems[p];

            if (item.instancesToPreload <= 0)
            {
                continue;
            }

            if (item.prefabTransform == null)
            {
                LevelSettings.LogIfNew("You have an item in Pool Boss with no prefab assigned at position: " + (p + 1));
                continue;
            }

            var itemName = item.prefabTransform.name;
            if (PoolItemsByName.ContainsKey(itemName))
            {
                LevelSettings.LogIfNew("You have more than one instance of '" + itemName + "' in Pool Boss. Skipping the second instance.");
                continue;
            }

            var itemClones = new List <Transform>();

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

            var instanceList = new PoolItemInstanceList(itemClones)
            {
                LogMessages          = item.logMessages,
                AllowInstantiateMore = item.allowInstantiateMore,
                SourceTrans          = item.prefabTransform,
                ItemHardLimit        = item.itemHardLimit,
                AllowRecycle         = item.allowRecycle
            };

            PoolItemsByName.Add(itemName, instanceList);
        }

        _isReady = true;
    }
        // This is just used for illustrative purposes. You might replace this with code to update a non-Unity GUI text element. If you use NGUI, please install the optional package "NGUI_CoreGameKit" to get an NGUI version of this script, replacing this one.
        // ReSharper disable once UnusedMember.Local
        private void OnGUI()
        {
            StringBuilder valFormatted = new StringBuilder();

            switch (vType)
            {
            case WorldVariableTracker.VariableType._integer:
                valFormatted.Append(_variableValue.ToString("N0"));


                if (!useCommaFormatting)
                {
                    valFormatted = valFormatted.Replace(",", "");
                }

                if (useFixedNumberOfDigits)
                {
                    while (valFormatted.Length < fixedDigitCount)
                    {
                        valFormatted.Insert(0, "0");
                    }
                }

                GUI.Label(new Rect(xStart, 120, 180, 40), variableName + ": " + valFormatted);
                break;

            case WorldVariableTracker.VariableType._float:
                valFormatted.Append(_variableFloatValue.ToString("N" + decimalPlaces));
                if (!useCommaFormatting)
                {
                    valFormatted = valFormatted.Replace(",", "");
                }

                if (useFixedNumberOfDigits)
                {
                    while (valFormatted.Length < fixedDigitCount)
                    {
                        valFormatted.Insert(0, "0");
                    }
                }

                GUI.Label(new Rect(xStart, 120, 180, 40), variableName + ": " + valFormatted);
                break;

            default:
                LevelSettings.LogIfNew("Add code for varType: " + vType.ToString());
                break;
            }
        }
 /// <summary>
 /// This returns an instance of the WorldVariable at runtime.
 /// </summary>
 /// <param name="statName">The World Variable name.</param>
 /// <returns>InGameWorldVariable object</returns>
 public static InGameWorldVariable GetWorldVariable(string statName)
 {
     if (InGamePlayerStats.ContainsKey(statName))
     {
         return(InGamePlayerStats[statName]);
     }
     if (statName == LevelSettings.DropDownNoneOption)
     {
         // don't log here.
     }
     else
     {
         LevelSettings.LogIfNew("Could not find World Variable '" + statName + "'.");
     }
     return(null);
 }
Пример #16
0
    /// <summary>
    /// Call this method to spawn a prefab using Pool Boss. All the Spawners and Killable use this method.
    /// </summary>
    /// <param name="transToSpawn">Transform to spawn</param>
    /// <param name="position">The position to spawn it at</param>
    /// <param name="rotation">The rotation to use</param>
    /// <param name="parentTransform">The parent Transform to use, if any (optional)</param>
    /// <returns>The Transform of the spawned object. It can be null if spawning failed from limits you have set.</returns>
    public static Transform Spawn(Transform transToSpawn, Vector3 position, Quaternion rotation, Transform parentTransform)
    {
        if (!_isReady)
        {
            LevelSettings.LogIfNew(NotInitError);
            return(null);
        }

        if (transToSpawn == null)
        {
            LevelSettings.LogIfNew("No Transform passed to Spawn method.");
            return(null);
        }

        if (Instance == null)
        {
            return(null);
        }

        var itemName = transToSpawn.name;

        if (PoolItemsByName.ContainsKey(itemName))
        {
            return(Spawn(itemName, position, rotation, parentTransform));
        }

        if (Instance.autoAddMissingPoolItems)
        {
            CreateMissingPoolItem(transToSpawn, itemName, true);
        }
        else
        {
            LevelSettings.LogIfNew("The Transform '" + itemName + "' passed to Spawn method is not configured in Pool Boss.");
            return(null);
        }

        return(Spawn(itemName, position, rotation, parentTransform));
    }
Пример #17
0
        public static object GetTypeValue(string typeName, string value)
        {
            switch (typeName)
            {
            case "System.String":
                return(value);

            case "System.Int32":
                return(Convert.ToInt32(value));

            case "System.Boolean":
                return(Convert.ToBoolean(value));

            case "System.Single":
                return(Convert.ToSingle(value));

            default:
                LevelSettings.LogIfNew("Unsupported type: " + typeName);
                break;
            }

            return(null);
        }
Пример #18
0
    /// <summary>
    /// This method will "Kill" all spawned instances of the prefab you pass in.
    /// </summary>
    /// <param name="transToKill">Transform component of a prefab</param>
    public static void KillAllOfPrefab(Transform transToKill)
    {
        if (Instance == null)
        {
            // Scene changing, do nothing.
            return;
        }

        if (transToKill == null)
        {
            LevelSettings.LogIfNew("No Transform passed to KillAllOfPrefab method.");
            return;
        }

        var itemName = GetPrefabName(transToKill);

        if (!PoolItemsByName.ContainsKey(itemName))
        {
            LevelSettings.LogIfNew("The Transform '" + itemName + "' passed to KillAllOfPrefab is not in Pool Boss. Not killing.");
            return;
        }

        var spawned = PoolItemsByName[itemName].SpawnedClones;

        var count = spawned.Count;

        for (var i = 0; i < spawned.Count && count > 0; i++)
        {
            var kill = spawned[i].GetComponent <Killable>();
            if (kill != null)
            {
                kill.DestroyKillable();
            }

            count--;
        }
    }
        private static void PlayMusic(LevelWaveMusicSettings musicSettings)
        {
            if (!_isValid)
            {
                LevelSettings.LogIfNew(
                    "WaveMusicChanger is not attached to any prefab with an AudioSource component. Music in Core GameKit LevelSettings will not play.");
                return;
            }

            if (_statListener != null)
            {
                _statListener.MusicChanging(musicSettings);
            }

            _isFading = false;

            switch (musicSettings.WaveMusicMode)
            {
            case LevelSettings.WaveMusicMode.PlayNew:
                _statAudio.Stop();
                _statAudio.clip   = musicSettings.WaveMusic;
                _statAudio.volume = musicSettings.WaveMusicVolume;
                _statAudio.Play();
                break;

            case LevelSettings.WaveMusicMode.Silence:
                _isFading        = true;
                _fadeStartTime   = Time.time;
                _fadeStartVolume = _statAudio.volume;
                _fadeTotalTime   = musicSettings.FadeTime;
                break;

            case LevelSettings.WaveMusicMode.KeepPreviousMusic:
                _statAudio.volume = musicSettings.WaveMusicVolume;
                break;
            }
        }
Пример #20
0
    void FillPool()
    {
        // fill weighted pool
        for (var item = 0; item < poolItems.Count; item++)
        {
            var poolItem = poolItems[item];

            var includeItem = true;

            switch (poolItem.activeMode)
            {
            case LevelSettings.ActiveItemMode.Always:
                break;

            case LevelSettings.ActiveItemMode.Never:
                continue;

            case LevelSettings.ActiveItemMode.IfWorldVariableInRange:
                if (poolItem.activeItemCriteria.statMods.Count == 0)
                {
                    includeItem = false;
                }

                // ReSharper disable once ForCanBeConvertedToForeach
                for (var i = 0; i < poolItem.activeItemCriteria.statMods.Count; i++)
                {
                    var stat = poolItem.activeItemCriteria.statMods[i];
                    if (!WorldVariableTracker.VariableExistsInScene(stat._statName))
                    {
                        Debug.LogError(string.Format("Prefab Pool '{0}' could not find World Variable '{1}', which is used in its Active Item Criteria.",
                                                     transform.name,
                                                     stat._statName));
                        includeItem = false;
                        break;
                    }

                    var variable = WorldVariableTracker.GetWorldVariable(stat._statName);
                    if (variable == null)
                    {
                        includeItem = false;
                        break;
                    }
                    var varVal = stat._varTypeToUse == WorldVariableTracker.VariableType._integer ? variable.CurrentIntValue : variable.CurrentFloatValue;

                    var min = stat._varTypeToUse == WorldVariableTracker.VariableType._integer ? stat._modValueIntMin : stat._modValueFloatMin;
                    var max = stat._varTypeToUse == WorldVariableTracker.VariableType._integer ? stat._modValueIntMax : stat._modValueFloatMax;

                    if (min > max)
                    {
                        LevelSettings.LogIfNew("The Min cannot be greater than the Max for Active Item Limit in Prefab Pool '" + transform.name + "'. Skipping item '" + poolItem.prefabToSpawn.name + "'.");
                        includeItem = false;
                        break;
                    }

                    if (!(varVal < min) && !(varVal > max))
                    {
                        continue;
                    }
                    includeItem = false;
                    break;
                }

                break;

            case LevelSettings.ActiveItemMode.IfWorldVariableOutsideRange:
                if (poolItem.activeItemCriteria.statMods.Count == 0)
                {
                    includeItem = false;
                }

                // ReSharper disable once ForCanBeConvertedToForeach
                for (var i = 0; i < poolItem.activeItemCriteria.statMods.Count; i++)
                {
                    var stat     = poolItem.activeItemCriteria.statMods[i];
                    var variable = WorldVariableTracker.GetWorldVariable(stat._statName);
                    if (variable == null)
                    {
                        includeItem = false;
                        break;
                    }
                    var varVal = stat._varTypeToUse == WorldVariableTracker.VariableType._integer ? variable.CurrentIntValue : variable.CurrentFloatValue;

                    var min = stat._varTypeToUse == WorldVariableTracker.VariableType._integer ? stat._modValueIntMin : stat._modValueFloatMin;
                    var max = stat._varTypeToUse == WorldVariableTracker.VariableType._integer ? stat._modValueIntMax : stat._modValueFloatMax;

                    if (min > max)
                    {
                        LevelSettings.LogIfNew("The Min cannot be greater than the Max for Active Item Limit in Prefab Pool '" + transform.name + "'. Skipping item '" + poolItem.prefabToSpawn.name + "'.");
                        includeItem = false;
                        break;
                    }

                    if (!(varVal >= min) || !(varVal <= max))
                    {
                        continue;
                    }
                    includeItem = false;
                    break;
                }

                break;
            }

            if (!includeItem)
            {
                continue;
            }

            for (var i = 0; i < poolItem.thisWeight.Value; i++)
            {
                _poolItemIndexes.Add(item);
            }
        }

        if (_poolItemIndexes.Count == 0)
        {
            LevelSettings.LogIfNew("The Prefab Pool '" + name + "' has no active Prefab Pool items. Please add some or delete the Prefab pool before continuing. Disabling Core GameKit.");
            LevelSettings.IsGameOver = true;
            return;
        }

        _isValid = true;
    }
Пример #21
0
        /*! \cond PRIVATE */
        public void ModifyVariable(WorldVariableModifier mod)
        {
            switch (mod._varTypeToUse)
            {
            case WorldVariableTracker.VariableType._integer:
                var modVal = mod._modValueIntAmt.Value;

                switch (mod._modValueIntAmt.curModMode)
                {
                case KillerVariable.ModMode.Add:
                    AddToIntValue(modVal);
                    break;

                case KillerVariable.ModMode.Set:
                    SetIntValueIfAllowed(modVal);
                    AddToIntValue(0);         // need to trigger game over if G.O. value reached
                    break;

                case KillerVariable.ModMode.Sub:
                    AddToIntValue(-modVal);
                    break;

                case KillerVariable.ModMode.Mult:
                    MultiplyByIntValue(modVal);
                    break;

                default:
                    LevelSettings.LogIfNew("Add code for modMode: " + mod._modValueIntAmt.curModMode.ToString());
                    break;
                }

                break;

            case WorldVariableTracker.VariableType._float:
                var modFloatVal = mod._modValueFloatAmt.Value;

                switch (mod._modValueFloatAmt.curModMode)
                {
                case KillerVariable.ModMode.Add:
                    AddToFloatValue(modFloatVal);
                    break;

                case KillerVariable.ModMode.Set:
                    SetFloatValueIfAllowed(modFloatVal);
                    AddToFloatValue(0f);
                    break;

                case KillerVariable.ModMode.Sub:
                    AddToFloatValue(-modFloatVal);
                    break;

                case KillerVariable.ModMode.Mult:
                    MultiplyByFloatValue(modFloatVal);
                    break;

                default:
                    LevelSettings.LogIfNew("Add code for modMode: " + mod._modValueIntAmt.curModMode.ToString());
                    break;
                }

                break;

            default:
                LevelSettings.LogIfNew("Add code for varType: " + mod._varTypeToUse.ToString());
                break;
            }
        }
        private static void Init()
        {
            if (_inGamePlayerStats != null)
            {
                return;
            }

            _doneInitializing = false;

            _inGamePlayerStats = new Dictionary <string, InGameWorldVariable>(StringComparer.OrdinalIgnoreCase);

            if (TrackerTransform == null)
            {
                return;
            }

            // set up variables for use
            for (var i = 0; i < TrackerTransform.childCount; i++)
            {
                var oTrans = TrackerTransform.GetChild(i);
                var oStat  = oTrans.GetComponent <WorldVariable>();

                if (oStat == null)
                {
                    LevelSettings.LogIfNew("Transform '" + oTrans.name +
                                           "' under WorldVariables does not contain a WorldVariable script. Please fix this.");
                    continue;
                }

                if (_inGamePlayerStats.ContainsKey(oStat.name))
                {
                    LevelSettings.LogIfNew("You have more than one World Variable named '" + oStat.name +
                                           "' in this Scene. Please make sure the names are unique.");
                    continue;
                }

                var newStatTracker = new InGameWorldVariable(oStat, oStat.name, oStat.varType);

                if (Application.isPlaying)
                {
                    // do not update values when we're in edit mode!
                    switch (oStat.persistanceMode)
                    {
                    case WorldVariable.StatPersistanceMode.ResetToStartingValue:
                        switch (oStat.varType)
                        {
                        case VariableType._integer:
                            newStatTracker.CurrentIntValue = oStat.startingValue;
                            break;

                        case VariableType._float:
                            newStatTracker.CurrentFloatValue = oStat.startingValueFloat;
                            break;
                        }
                        break;

                    case WorldVariable.StatPersistanceMode.KeepFromPrevious:
                        // set to value in player prefs
                        break;
                    }

                    if (oStat.listenerPrefab != null)
                    {
                        var variable = GetExistingWorldVariableIntValue(oStat.name, oStat.startingValue);
                        if (variable != null)
                        {
                            oStat.listenerPrefab.UpdateValue(variable.Value, variable.Value);
                        }
                    }
                }

                _inGamePlayerStats.Add(oStat.name, newStatTracker);
            }

            _doneInitializing = true;
        }
Пример #23
0
    /// <summary>
    /// Call this method to spawn a prefab using Pool Boss. All the Spawners and Killable use this method.
    /// </summary>
    /// <param name="itemName">Name of the transform to spawn</param>
    /// <param name="position">The position to spawn it at</param>
    /// <param name="rotation">The rotation to use</param>
    /// <param name="parentTransform">The parent Transform to use, if any (optional)</param>
    /// <returns>The Transform of the spawned object. It can be null if spawning failed from limits you have set.</returns>
    public static Transform Spawn(string itemName, Vector3 position, Quaternion rotation,
                                  Transform parentTransform)
    {
        var itemSettings = PoolItemsByName[itemName];

        Transform cloneToSpawn = null;

        if (itemSettings.DespawnedClones.Count == 0)
        {
            if (!itemSettings.AllowInstantiateMore)
            {
                if (itemSettings.AllowRecycle)
                {
                    cloneToSpawn = itemSettings.SpawnedClones[0];
                }
                else
                {
                    LevelSettings.LogIfNew("The Transform '" + itemName + "' has no available clones left to Spawn in Pool Boss. Please increase your Preload Qty, turn on Allow Instantiate More or turn on Recycle Oldest (Recycle is only for non-essential things like decals).", true);
                    return(null);
                }
            }
            else
            {
                // Instantiate a new one
                var curCount = NumberOfClones(itemSettings);
                if (curCount >= itemSettings.ItemHardLimit)
                {
                    LevelSettings.LogIfNew("The Transform '" + itemName + "' has reached its item limit in Pool Boss. Please increase your Preload Qty or Item Limit.", true);
                    return(null);
                }

                var createdObjTransform = InstantiateForPool(itemSettings.SourceTrans, curCount + 1);
                itemSettings.DespawnedClones.Add(createdObjTransform);

                if (Instance.logMessages || itemSettings.LogMessages)
                {
                    Debug.LogWarning("Pool Boss Instantiated an extra '" + itemName + "' at " + Time.time + " because there were none left in the Pool.");
                }
            }
        }

        if (cloneToSpawn == null)
        {
            var randomIndex = Random.Range(0, itemSettings.DespawnedClones.Count);
            cloneToSpawn = itemSettings.DespawnedClones[randomIndex];
        }
        else     // recycling
        {
            cloneToSpawn.BroadcastMessage(DespawnedMessageName, SendMessageOptions.DontRequireReceiver);
        }

        if (cloneToSpawn == null)
        {
            LevelSettings.LogIfNew("One or more of the prefab '" + itemName + "' in Pool Boss has been destroyed. You should never destroy objects in the Pool. Despawn instead. Not spawning anything for this call.");
            return(null);
        }

        cloneToSpawn.position = position;
        cloneToSpawn.rotation = rotation;
        SpawnUtility.SetActive(cloneToSpawn.gameObject, true);
        Instance._changes++;

        if (Instance.logMessages || itemSettings.LogMessages)
        {
            Debug.Log("Pool Boss spawned '" + itemName + "' at " + Time.time);
        }

        if (parentTransform != null)
        {
            SetParent(cloneToSpawn, parentTransform);
        }

        cloneToSpawn.BroadcastMessage(SpawnedMessageName, SendMessageOptions.DontRequireReceiver);

        itemSettings.DespawnedClones.Remove(cloneToSpawn);
        itemSettings.SpawnedClones.Add(cloneToSpawn);

        return(cloneToSpawn);
    }
Пример #24
0
    // ReSharper disable once FunctionComplexityOverflow
    public override void OnInspectorGUI()
    {
        EditorGUI.indentLevel = 0;

        _pool = (PoolBoss)target;

        _isDirty = false;
        LevelSettings.Instance = null; // clear cached version

        DTInspectorUtility.DrawTexture(CoreGameKitInspectorResources.LogoTexture);

        var isInProjectView = DTInspectorUtility.IsPrefabInProjectView(_pool);

        if (isInProjectView)
        {
            DTInspectorUtility.ShowRedErrorBox("You have selected the PoolBoss prefab in Project View. Please select the one in your Scene to edit.");
            return;
        }

        var catNames = new List <string>(_pool._categories.Count);

        // ReSharper disable once ForCanBeConvertedToForeach
        for (var i = 0; i < _pool._categories.Count; i++)
        {
            catNames.Add(_pool._categories[i].CatName);
        }

        if (!Application.isPlaying)
        {
            DTInspectorUtility.StartGroupHeader();
            var newCat = EditorGUILayout.TextField("New Category Name", _pool.newCategoryName);
            if (newCat != _pool.newCategoryName)
            {
                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "change New Category Name");
                _pool.newCategoryName = newCat;
            }
            EditorGUILayout.EndVertical();
            EditorGUILayout.BeginHorizontal();
            GUI.contentColor = DTInspectorUtility.BrightButtonColor;
            GUILayout.Space(10);
            if (GUILayout.Button("Create New Category", EditorStyles.toolbarButton, GUILayout.Width(130)))
            {
                CreateCategory();
            }
            GUI.contentColor = Color.white;

            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();
            DTInspectorUtility.AddSpaceForNonU5();
            DTInspectorUtility.ResetColors();

            var selCatIndex = catNames.IndexOf(_pool.addToCategoryName);

            if (selCatIndex == -1)
            {
                selCatIndex = 0;
                _isDirty    = true;
            }

            GUI.backgroundColor = DTInspectorUtility.BrightButtonColor;

            var newIndex = EditorGUILayout.Popup("Default Item Category", selCatIndex, catNames.ToArray());
            if (newIndex != selCatIndex)
            {
                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "change Default Item Category");
                _pool.addToCategoryName = catNames[newIndex];
            }
            GUI.backgroundColor = Color.white;
            GUI.contentColor    = Color.white;
        }

        GUI.contentColor = Color.white;

        if (!Application.isPlaying)
        {
            var maxFrames = Math.Min(100, _pool.poolItems.Count);
            maxFrames = Math.Max(1, maxFrames);
            var newFrames = EditorGUILayout.IntSlider(new GUIContent("Initialize Time (Frames)", "You can increase this value to make the initial pool creation take more frames. Defaults to 1. Max of the 100 or number of different prefabs, whichever is less."), _pool.framesForInit, 1, maxFrames);
            if (newFrames != _pool.framesForInit)
            {
                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "change Initialize Time (Frames)");
                _pool.framesForInit = newFrames;
            }
        }

        PoolBossItem     itemToRemove     = null;
        int?             indexToInsertAt  = null;
        PoolBossCategory selectedCategory = null;
        PoolBossItem     itemToClone      = null;

        PoolBossCategory catEditing  = null;
        PoolBossCategory catRenaming = null;

        PoolBossCategory catToDelete = null;
        int?indexToShiftUp           = null;
        int?indexToShiftDown         = null;

        var visiblePoolItems = _pool.poolItems;

        // ReSharper disable once ForCanBeConvertedToForeach
        for (var i = 0; i < visiblePoolItems.Count; i++)
        {
            var item = visiblePoolItems[i];
            if (catNames.Contains(item.categoryName))
            {
                continue;
            }

            item.categoryName = catNames[0];
            _isDirty          = true;
        }

        var newAutoAdd = EditorGUILayout.Toggle(new GUIContent("Auto-Add Missing Items", "Auto-Add Missing Items to top Category"), _pool.autoAddMissingPoolItems);

        if (newAutoAdd != _pool.autoAddMissingPoolItems)
        {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "toggle Auto-Add Missing Items");
            _pool.autoAddMissingPoolItems = newAutoAdd;
        }

        var newLog = EditorGUILayout.Toggle("Log Messages", _pool.logMessages);

        if (newLog != _pool.logMessages)
        {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "toggle Log Messages");
            _pool.logMessages = newLog;
        }

        var newFilter = EditorGUILayout.Toggle("Use Text Item Filter", _pool.useTextFilter);

        if (newFilter != _pool.useTextFilter)
        {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "toggle Use Text Item Filter");
            _pool.useTextFilter = newFilter;
        }

        bool hasFiltered = false;

        if (_pool.useTextFilter)
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(10);
            GUILayout.Label("Text Group Filter", GUILayout.Width(140));
            var newTextFilter = GUILayout.TextField(_pool.textFilter, GUILayout.Width(180));
            if (newTextFilter != _pool.textFilter)
            {
                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "change Text Item Filter");
                _pool.textFilter = newTextFilter;
            }
            GUILayout.Space(10);
            GUI.contentColor = DTInspectorUtility.BrightButtonColor;
            if (GUILayout.Button("Clear", EditorStyles.toolbarButton, GUILayout.Width(70)))
            {
                _pool.textFilter = string.Empty;
            }
            GUI.contentColor = Color.white;
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Separator();

            var unfilteredCount = visiblePoolItems.Count;

            if (!string.IsNullOrEmpty(_pool.textFilter))
            {
                visiblePoolItems = visiblePoolItems.FindAll(delegate(PoolBossItem x) {
                    return(x.prefabTransform != null && x.prefabTransform.name.IndexOf(_pool.textFilter, StringComparison.OrdinalIgnoreCase) >= 0);
                });
            }

            var hiddenCount = unfilteredCount - visiblePoolItems.Count;
            if (hiddenCount > 0)
            {
                DTInspectorUtility.ShowLargeBarAlertBox(string.Format("{0}/{1} item(s) filtered out.", hiddenCount, unfilteredCount));
                hasFiltered = true;
            }
        }

        var hadNoListener = _pool.listener == null;
        var newListener   = (PoolBossListener)EditorGUILayout.ObjectField("Listener", _pool.listener, typeof(PoolBossListener), true);

        if (newListener != _pool.listener)
        {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "assign Listener");
            _pool.listener = newListener;
            if (hadNoListener && _pool.listener != null)
            {
                _pool.listener.sourceTransName = _pool.transform.name;
            }
        }

        var newShow = EditorGUILayout.Toggle("Show Legend", _pool.showLegend);

        if (newShow != _pool.showLegend)
        {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "toggle Show Legend");
            _pool.showLegend = newShow;
        }

        if (_pool.showLegend)
        {
            GUI.contentColor = DTInspectorUtility.BrightButtonColor;
            DTInspectorUtility.BeginGroupedControls();

            GUILayout.Label("Legend", EditorStyles.boldLabel);

            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(6);
            GUILayout.Button(
                new GUIContent(CoreGameKitInspectorResources.DamageTexture,
                               "Click to deal 1 damage to all Killables"), EditorStyles.toolbarButton, GUILayout.Width(24));
            GUILayout.Label("Deal 1 Damage To All");

            GUILayout.Space(6);
            GUILayout.Button(
                new GUIContent(CoreGameKitInspectorResources.KillTexture, "Click to kill all Killables"),
                EditorStyles.toolbarButton, GUILayout.Width(24));
            GUILayout.Label("Kill All");

            GUILayout.Space(6);
            GUILayout.Button(
                new GUIContent(CoreGameKitInspectorResources.DespawnTexture, "Click to despawn prefabs"),
                EditorStyles.toolbarButton, GUILayout.Width(24));
            GUILayout.Label("Despawn All");

            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();
            DTInspectorUtility.EndGroupedControls();
            EditorGUILayout.Separator();
        }

        EditorGUI.indentLevel = 0;
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Actions", GUILayout.Width(100));
        GUI.contentColor = DTInspectorUtility.BrightButtonColor;

        GUILayout.FlexibleSpace();

        var allExpanded = true;

        // ReSharper disable once ForCanBeConvertedToForeach
        for (var i = 0; i < _pool._categories.Count; i++)
        {
            if (_pool._categories[i].IsExpanded)
            {
                continue;
            }
            allExpanded = false;
            break;
        }

        // ReSharper disable once ForCanBeConvertedToForeach
        for (var i = 0; i < visiblePoolItems.Count; i++)
        {
            if (visiblePoolItems[i].isExpanded)
            {
                continue;
            }
            allExpanded = false;
            break;
        }

        if (Application.isPlaying)
        {
            if (GUILayout.Button(new GUIContent("Clear Peaks"), EditorStyles.toolbarButton, GUILayout.Width(80)))
            {
                ClearAllPeaks();
                _isDirty = true;
            }

            GUILayout.Space(6);
        }

        var buttonTooltip = allExpanded ? "Click to collapse all categories and items" : "Click to expand all categories and items";
        var buttonText    = allExpanded ? "Collapse All" : "Expand All";

        if (GUILayout.Button(new GUIContent(buttonText, buttonTooltip), EditorStyles.toolbarButton, GUILayout.Width(80)))
        {
            ExpandCollapseAll(!allExpanded);
        }

        if (Application.isPlaying)
        {
            if (GUILayout.Button(new GUIContent(CoreGameKitInspectorResources.DamageTexture, "Click to deal 1 damage to all Killables"), EditorStyles.toolbarButton, GUILayout.Width(24)))
            {
                SpawnUtility.DamageAllPrefabs(1);
                _isDirty = true;
            }

            if (GUILayout.Button(new GUIContent(CoreGameKitInspectorResources.KillTexture, "Click to kill all Killables"), EditorStyles.toolbarButton, GUILayout.Width(24)))
            {
                SpawnUtility.KillAllPrefabs();
                _isDirty = true;
            }

            if (GUILayout.Button(new GUIContent(CoreGameKitInspectorResources.DespawnTexture, "Click to despawn prefabs"), EditorStyles.toolbarButton, GUILayout.Width(24)))
            {
                SpawnUtility.DespawnAllPrefabs();
                _isDirty = true;
            }
            GUILayout.Space(6);
        }

        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Separator();

        GUI.backgroundColor = Color.white;

        if (!Application.isPlaying)
        {
            EditorGUILayout.BeginVertical();
            var anEvent = Event.current;

            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(4);
            GUI.color = DTInspectorUtility.DragAreaColor;
            var dragArea = GUILayoutUtility.GetRect(0f, 30f, GUILayout.ExpandWidth(true));
            GUI.Box(dragArea, "Drag prefabs here in bulk to add them to the Pool!");
            GUI.color = Color.white;

            switch (anEvent.type)
            {
            case EventType.DragUpdated:
            case EventType.DragPerform:
                if (!dragArea.Contains(anEvent.mousePosition))
                {
                    break;
                }

                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                if (anEvent.type == EventType.DragPerform)
                {
                    DragAndDrop.AcceptDrag();

                    foreach (var dragged in DragAndDrop.objectReferences)
                    {
                        AddPoolItem(dragged);
                    }
                }
                Event.current.Use();
                break;
            }
            GUILayout.Space(4);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();

            DTInspectorUtility.VerticalSpace(4);
        }

        GUI.backgroundColor = Color.white;
        GUI.contentColor    = Color.white;

        // ReSharper disable once ForCanBeConvertedToForeach
        for (var c = 0; c < _pool._categories.Count; c++)
        {
            var cat = _pool._categories[c];

            EditorGUI.indentLevel = 0;

            var matchingItems = new List <PoolBossItem>();
            matchingItems.AddRange(visiblePoolItems);
            matchingItems.RemoveAll(delegate(PoolBossItem x) {
                return(x.categoryName != cat.CatName);
            });

            var hasItems = matchingItems.Count > 0;

            EditorGUILayout.BeginHorizontal();

            if (!cat.IsEditing || Application.isPlaying)
            {
                var catName = cat.CatName;

                catName += ": " + matchingItems.Count + " item" + ((matchingItems.Count != 1) ? "s" : "");

                var state = cat.IsExpanded;
                var text  = catName;

                // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                if (!state)
                {
                    GUI.backgroundColor = DTInspectorUtility.InactiveHeaderColor;
                }
                else
                {
                    GUI.backgroundColor = DTInspectorUtility.ActiveHeaderColor;
                }

                text = "<b><size=11>" + text + "</size></b>";

                if (state)
                {
                    text = "\u25BC " + text;
                }
                else
                {
                    text = "\u25BA " + text;
                }
                if (!GUILayout.Toggle(true, text, "dragtab", GUILayout.MinWidth(20f)))
                {
                    state = !state;
                }

                GUILayout.Space(2f);

                if (state != cat.IsExpanded)
                {
                    UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "toggle expand Pool Boss Category");
                    cat.IsExpanded = state;
                }

                var catItemsCollapsed = true;

                for (var i = 0; i < visiblePoolItems.Count; i++)
                {
                    var item = visiblePoolItems[i];
                    if (item.categoryName != cat.CatName)
                    {
                        continue;
                    }

                    if (!item.isExpanded)
                    {
                        continue;
                    }
                    catItemsCollapsed = false;
                    break;
                }

                GUI.backgroundColor = Color.white;

                var tooltip = catItemsCollapsed ? "Click to expand all items in this category" : "Click to collapse all items in this category";
                var btnText = catItemsCollapsed ? "Expand" : "Collapse";

                GUI.contentColor = DTInspectorUtility.BrightButtonColor;
                if (GUILayout.Button(new GUIContent(btnText, tooltip), EditorStyles.toolbarButton, GUILayout.Width(60), GUILayout.Height(16)))
                {
                    ExpandCollapseCategory(cat.CatName, catItemsCollapsed);
                }
                GUI.contentColor = Color.white;

                if (!Application.isPlaying)
                {
                    if (c > 0)
                    {
                        // the up arrow.
                        var upArrow = CoreGameKitInspectorResources.UpArrowTexture;
                        if (GUILayout.Button(new GUIContent(upArrow, "Click to shift Category up"),
                                             EditorStyles.toolbarButton, GUILayout.Width(24), GUILayout.Height(16)))
                        {
                            indexToShiftUp = c;
                        }
                    }
                    else
                    {
                        GUILayout.Button("", EditorStyles.toolbarButton, GUILayout.Width(24), GUILayout.Height(16));
                    }

                    if (c < _pool._categories.Count - 1)
                    {
                        // The down arrow will move things towards the end of the List
                        var dnArrow = CoreGameKitInspectorResources.DownArrowTexture;
                        if (GUILayout.Button(new GUIContent(dnArrow, "Click to shift Category down"),
                                             EditorStyles.toolbarButton, GUILayout.Width(24), GUILayout.Height(16)))
                        {
                            indexToShiftDown = c;
                        }
                    }
                    else
                    {
                        GUILayout.Button("", EditorStyles.toolbarButton, GUILayout.Width(24), GUILayout.Height(16));
                    }

                    var settingsIcon = new GUIContent(CoreGameKitInspectorResources.SettingsTexture,
                                                      "Click to edit Category");

                    GUI.backgroundColor = Color.white;
                    if (GUILayout.Button(settingsIcon, EditorStyles.toolbarButton, GUILayout.Width(24),
                                         GUILayout.Height(16)))
                    {
                        catEditing = cat;
                    }
                    GUI.backgroundColor = DTInspectorUtility.DeleteButtonColor;
                    if (GUILayout.Button(new GUIContent("Delete", "Click to delete Category"),
                                         EditorStyles.miniButton, GUILayout.MaxWidth(45)))
                    {
                        catToDelete = cat;
                    }
                    GUILayout.Space(15);
                }
                else
                {
                    GUI.contentColor = DTInspectorUtility.BrightButtonColor;

                    if (GUILayout.Button(new GUIContent(CoreGameKitInspectorResources.DamageTexture, "Click to damage all Killables in this Category"), EditorStyles.toolbarButton, GUILayout.Width(24)))
                    {
                        SpawnUtility.DamageAllPrefabsInCategory(cat.CatName, 1);
                        _isDirty = true;
                    }
                    if (GUILayout.Button(new GUIContent(CoreGameKitInspectorResources.KillTexture, "Click to kill all Killables in this Category"), EditorStyles.toolbarButton, GUILayout.Width(24)))
                    {
                        SpawnUtility.KillAllPrefabsInCategory(cat.CatName);
                        _isDirty = true;
                    }
                    if (GUILayout.Button(new GUIContent(CoreGameKitInspectorResources.DespawnTexture, "Click to despawn all prefabs in this Category"), EditorStyles.toolbarButton, GUILayout.Width(24)))
                    {
                        SpawnUtility.DespawnAllPrefabsInCategory(cat.CatName);
                        _isDirty = true;
                    }

                    var itemsSpawned            = PoolBoss.CategoryItemsSpawned(cat.CatName);
                    var categoryHasItemsSpawned = itemsSpawned > 0;
                    var theBtnText = itemsSpawned.ToString();
                    var btnColor   = categoryHasItemsSpawned ? DTInspectorUtility.BrightTextColor : DTInspectorUtility.DeleteButtonColor;
                    GUI.backgroundColor = btnColor;

                    var btnWidth = 32;
                    if (theBtnText.Length > 3)
                    {
                        btnWidth = 11 * theBtnText.Length;
                    }
                    if (GUILayout.Button(theBtnText, EditorStyles.miniButtonRight, GUILayout.MaxWidth(btnWidth)) && categoryHasItemsSpawned)
                    {
                        var catItems = PoolBoss.CategoryActiveItems(cat.CatName);

                        if (catItems.Count > 0)
                        {
                            var gos = new List <GameObject>(catItems.Count);
                            for (var i = 0; i < catItems.Count; i++)
                            {
                                gos.Add(catItems[i].gameObject);
                            }

                            Selection.objects = gos.ToArray();
                        }
                    }

                    GUI.backgroundColor = Color.white;
                    GUI.contentColor    = Color.white;
                    GUILayout.Space(4);
                }
            }
            else
            {
                GUI.backgroundColor = DTInspectorUtility.BrightTextColor;
                var tex = EditorGUILayout.TextField("", cat.ProspectiveName);
                if (tex != cat.ProspectiveName)
                {
                    cat.ProspectiveName = tex;
                    _isDirty            = true;
                }

                var buttonPressed = DTInspectorUtility.AddCancelSaveButtons("category");

                switch (buttonPressed)
                {
                case DTInspectorUtility.FunctionButtons.Cancel:
                    cat.IsEditing       = false;
                    cat.ProspectiveName = cat.CatName;
                    _isDirty            = true;
                    break;

                case DTInspectorUtility.FunctionButtons.Save:
                    catRenaming = cat;
                    break;
                }

                GUILayout.Space(15);
            }

            GUI.backgroundColor = Color.white;
            EditorGUILayout.EndHorizontal();

            if (cat.IsEditing)
            {
                DTInspectorUtility.VerticalSpace(2);
            }

            matchingItems.Sort(delegate(PoolBossItem x, PoolBossItem y) {
                if (x.prefabTransform == null && y.prefabTransform != null)
                {
                    return(-1);
                }
                if (y.prefabTransform == null && x.prefabTransform != null)
                {
                    return(1);
                }
                if (y.prefabTransform == null && x.prefabTransform == null)
                {
                    return(0);
                }

                // ReSharper disable PossibleNullReferenceException
                return(String.Compare(x.prefabTransform.name, y.prefabTransform.name, StringComparison.Ordinal));
                // ReSharper restore PossibleNullReferenceException
            });

            var catItemsFiltered = 0;
            if (hasFiltered)
            {
                var totalCount = _pool.poolItems.FindAll(delegate(PoolBossItem x) {
                    return(cat.CatName == x.categoryName);
                }).Count;

                catItemsFiltered = totalCount - matchingItems.Count;
            }

            bool hasOpenBox = false;

            if (catItemsFiltered > 0)
            {
                DTInspectorUtility.BeginGroupedControls();
                DTInspectorUtility.ShowLargeBarAlertBox(string.Format("This Category has {0} items filtered out.", catItemsFiltered));
                hasOpenBox = true;
            }
            else if (!hasItems)
            {
                DTInspectorUtility.BeginGroupedControls();
                DTInspectorUtility.ShowLargeBarAlertBox("This Category is empty. Add / move some items or you may delete it.");
                DTInspectorUtility.EndGroupedControls();
            }

            if (cat.IsExpanded)
            {
                if (matchingItems.Count > 0 && !hasOpenBox)
                {
                    DTInspectorUtility.BeginGroupedControls();
                }

                for (var i = 0; i < matchingItems.Count; i++)
                {
                    var poolItem = matchingItems[i];

                    DTInspectorUtility.StartGroupHeader();

                    if (poolItem.prefabTransform != null)
                    {
                        var rend = poolItem.prefabTransform.GetComponent <TrailRenderer>();
                        if (rend != null && rend.autodestruct)
                        {
                            DTInspectorUtility.ShowRedErrorBox(
                                "This prefab contains a Trail Renderer with auto-destruct enabled. " + DoNotDestroyPoolItem);
                        }
                        else
                        {
#if UNITY_5_4_OR_NEWER
                            // nothing to check
#else
                            var partAnim = poolItem.prefabTransform.GetComponent <ParticleAnimator>();
                            if (partAnim != null && partAnim.autodestruct)
                            {
                                DTInspectorUtility.ShowRedErrorBox(
                                    "This prefab contains a Particle Animator with auto-destruct enabled. " + DoNotDestroyPoolItem);
                            }
#endif
                        }
                    }

                    EditorGUI.indentLevel = 1;
                    EditorGUILayout.BeginHorizontal();
                    var itemName = poolItem.prefabTransform == null ? "[NO PREFAB]" : poolItem.prefabTransform.name;
                    var state    = DTInspectorUtility.Foldout(poolItem.isExpanded, itemName);
                    if (state != poolItem.isExpanded)
                    {
                        UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "toggle expand Pool Item");
                        poolItem.isExpanded = state;
                    }

                    if (Application.isPlaying)
                    {
                        GUILayout.FlexibleSpace();

                        if (poolItem.prefabTransform != null)
                        {
                            var itemInfo = PoolBoss.PoolItemInfoByName(itemName);
                            GUI.contentColor = DTInspectorUtility.BrightButtonColor;

                            if (itemInfo != null && itemInfo.SpawnedClones.Count > 0)
                            {
                                if (poolItem.prefabTransform.GetComponent <Killable>() != null)
                                {
                                    if (GUILayout.Button(new GUIContent(CoreGameKitInspectorResources.DamageTexture, "Click to damage all of this prefab"), EditorStyles.toolbarButton, GUILayout.Width(24)))
                                    {
                                        SpawnUtility.DamageAllOfPrefab(poolItem.prefabTransform, 1);
                                        _isDirty = true;
                                    }
                                    if (GUILayout.Button(new GUIContent(CoreGameKitInspectorResources.KillTexture, "Click to kill all of this prefab"), EditorStyles.toolbarButton, GUILayout.Width(24)))
                                    {
                                        SpawnUtility.KillAllOfPrefab(poolItem.prefabTransform);
                                        _isDirty = true;
                                    }
                                }
                                if (GUILayout.Button(new GUIContent(CoreGameKitInspectorResources.DespawnTexture, "Click to despawn all of this prefab"),
                                                     EditorStyles.toolbarButton, GUILayout.Width(24)))
                                {
                                    SpawnUtility.DespawnAllOfPrefab(poolItem.prefabTransform);
                                    _isDirty = true;
                                }
                            }

                            GUI.contentColor = DTInspectorUtility.BrightTextColor;
                            if (itemInfo != null)
                            {
                                var spawnedCount   = itemInfo.SpawnedClones.Count;
                                var despawnedCount = itemInfo.DespawnedClones.Count;
                                // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                                if (spawnedCount == 0)
                                {
                                    GUI.backgroundColor = DTInspectorUtility.DeleteButtonColor;
                                }
                                else
                                {
                                    GUI.backgroundColor = DTInspectorUtility.BrightTextColor;
                                }
                                var content = new GUIContent(string.Format("{0} / {1} Spawned", spawnedCount, despawnedCount + spawnedCount),
                                                             "Click here to select all spawned items.");
                                if (GUILayout.Button(content, EditorStyles.toolbarButton, GUILayout.Width(110)))
                                {
                                    var obj = new List <GameObject>();
                                    foreach (var t in itemInfo.SpawnedClones)
                                    {
                                        if (t == null)
                                        {
                                            LevelSettings.LogIfNew("1 of more of your pooled Game Object has been destroyed! Please check for any scripts that destroy Game Objects. Pool Boss cannot recover from this.");
                                            continue;
                                        }
                                        obj.Add(t.gameObject);
                                    }

                                    if (obj.Count > 0)
                                    {
                                        Selection.objects = obj.ToArray();
                                    }
                                }

                                content = new GUIContent("Pk: " + itemInfo.Peak, "Click to reset peak to zero.");
                                if (Time.realtimeSinceStartup - itemInfo.PeakTime < .2f)
                                {
                                    GUI.backgroundColor = DTInspectorUtility.AddButtonColor;
                                }
                                else if (itemInfo.Peak == 0)
                                {
                                    GUI.backgroundColor = DTInspectorUtility.DeleteButtonColor;
                                }
                                else
                                {
                                    GUI.backgroundColor = DTInspectorUtility.BrightTextColor;
                                }

                                if (GUILayout.Button(content, EditorStyles.miniButton, GUILayout.Width(64)))
                                {
                                    itemInfo.Peak     = Math.Max(0, itemInfo.SpawnedClones.Count);
                                    itemInfo.PeakTime = Time.realtimeSinceStartup;
                                    _isDirty          = true;
                                    _pool._changes++;
                                }
                                GUI.backgroundColor = Color.white;
                            }
                        }
                        GUI.contentColor = Color.white;
                    }
                    else
                    {
                        GUI.backgroundColor = DTInspectorUtility.BrightButtonColor;
                        var selCatIndex = catNames.IndexOf(poolItem.categoryName);
                        var newCat      = EditorGUILayout.Popup(selCatIndex, catNames.ToArray(), GUILayout.Width(130));
                        if (newCat != selCatIndex)
                        {
                            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "change Pool Item Category");
                            poolItem.categoryName = catNames[newCat];
                        }
                        GUI.backgroundColor = Color.white;

                        DTInspectorUtility.FocusInProjectViewButton("Pool Item prefab", poolItem.prefabTransform == null ? null : poolItem.prefabTransform.gameObject);
                    }

                    var buttonPressed = DTInspectorUtility.AddFoldOutListItemButtons(i, matchingItems.Count,
                                                                                     "Pool Item", false, null, true, false, true);
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndVertical();

                    if (poolItem.isExpanded)
                    {
                        EditorGUI.indentLevel = 0;

                        var newPrefab =
                            (Transform)
                            EditorGUILayout.ObjectField("Prefab", poolItem.prefabTransform, typeof(Transform),
                                                        false);
                        if (newPrefab != poolItem.prefabTransform)
                        {
                            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "change Pool Item Prefab");
                            poolItem.prefabTransform = newPrefab;
                        }

                        var newPreloadQty = EditorGUILayout.IntSlider("Preload Qty", poolItem.instancesToPreload, 0,
                                                                      10000);
                        if (newPreloadQty != poolItem.instancesToPreload)
                        {
                            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool,
                                                                   "change Pool Item Preload Qty");
                            poolItem.instancesToPreload = newPreloadQty;
                        }
                        if (poolItem.instancesToPreload == 0)
                        {
                            DTInspectorUtility.ShowColorWarningBox(
                                "You have set the Preload Qty to 0. This prefab will not be in the Pool.");
                        }

                        var newAllow = EditorGUILayout.Toggle("Allow Instantiate More",
                                                              poolItem.allowInstantiateMore);
                        if (newAllow != poolItem.allowInstantiateMore)
                        {
                            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool,
                                                                   "toggle Allow Instantiate More");
                            poolItem.allowInstantiateMore = newAllow;
                        }

                        if (poolItem.allowInstantiateMore)
                        {
                            var newLimit = EditorGUILayout.IntSlider("Item Limit", poolItem.itemHardLimit,
                                                                     poolItem.instancesToPreload, 10000);
                            if (newLimit != poolItem.itemHardLimit)
                            {
                                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "change Item Limit");
                                poolItem.itemHardLimit = newLimit;
                            }
                        }
                        else
                        {
                            var newRecycle = EditorGUILayout.Toggle("Recycle Oldest", poolItem.allowRecycle);
                            if (newRecycle != poolItem.allowRecycle)
                            {
                                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "toggle Recycle Oldest");
                                poolItem.allowRecycle = newRecycle;
                            }
                        }

                        newLog = EditorGUILayout.Toggle("Log Messages", poolItem.logMessages);
                        if (newLog != poolItem.logMessages)
                        {
                            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "toggle Log Messages");
                            poolItem.logMessages = newLog;
                        }
                    }

                    switch (buttonPressed)
                    {
                    case DTInspectorUtility.FunctionButtons.Remove:
                        itemToRemove = poolItem;
                        break;

                    case DTInspectorUtility.FunctionButtons.Add:
                        indexToInsertAt  = _pool.poolItems.IndexOf(poolItem);
                        selectedCategory = cat;
                        break;

                    case DTInspectorUtility.FunctionButtons.DespawnAll:
                        PoolBoss.DespawnAllOfPrefab(poolItem.prefabTransform);
                        break;

                    case DTInspectorUtility.FunctionButtons.Copy:
                        itemToClone = poolItem;
                        break;
                    }

                    EditorGUILayout.EndVertical();
                    DTInspectorUtility.AddSpaceForNonU5();
                }

                if (matchingItems.Count > 0 && !hasOpenBox)
                {
                    DTInspectorUtility.EndGroupedControls();
                    DTInspectorUtility.VerticalSpace(2);
                }
            }

            if (hasOpenBox)
            {
                DTInspectorUtility.EndGroupedControls();
            }

            DTInspectorUtility.VerticalSpace(2);
        }

        if (indexToShiftUp.HasValue)
        {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "shift up Category");
            var item = _pool._categories[indexToShiftUp.Value];
            _pool._categories.Insert(indexToShiftUp.Value - 1, item);
            _pool._categories.RemoveAt(indexToShiftUp.Value + 1);
            _isDirty = true;
        }

        if (indexToShiftDown.HasValue)
        {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "shift down Category");
            var index = indexToShiftDown.Value + 1;
            var item  = _pool._categories[index];
            _pool._categories.Insert(index - 1, item);
            _pool._categories.RemoveAt(index + 1);
            _isDirty = true;
        }

        if (catToDelete != null)
        {
            if (_pool.poolItems.FindAll(delegate(PoolBossItem x) {
                return(x.categoryName == catToDelete.CatName);
            }).Count > 0)
            {
                DTInspectorUtility.ShowAlert("You cannot delete a Category with Pool Items in it. Move or delete the items first.");
            }
            else if (_pool._categories.Count <= 1)
            {
                DTInspectorUtility.ShowAlert("You cannot delete the last Category.");
            }
            else
            {
                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "Delete Category");
                _pool._categories.Remove(catToDelete);
                _isDirty = true;
            }
        }

        if (catRenaming != null)
        {
            // ReSharper disable once ForCanBeConvertedToForeach
            var isValidName = true;

            if (string.IsNullOrEmpty(catRenaming.ProspectiveName))
            {
                isValidName = false;
                DTInspectorUtility.ShowAlert("You cannot have a blank Category name.");
            }

            // ReSharper disable once ForCanBeConvertedToForeach
            for (var c = 0; c < _pool._categories.Count; c++)
            {
                var cat = _pool._categories[c];
                // ReSharper disable once InvertIf
                if (cat != catRenaming && cat.CatName == catRenaming.ProspectiveName)
                {
                    isValidName = false;
                    DTInspectorUtility.ShowAlert("You already have a Category named '" + catRenaming.ProspectiveName + "'. Category names must be unique.");
                }
            }

            if (isValidName)
            {
                UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "Undo change Category name.");

                // ReSharper disable once ForCanBeConvertedToForeach
                for (var i = 0; i < _pool.poolItems.Count; i++)
                {
                    var item = _pool.poolItems[i];
                    if (item.categoryName == catRenaming.CatName)
                    {
                        item.categoryName = catRenaming.ProspectiveName;
                    }
                }

                catRenaming.CatName   = catRenaming.ProspectiveName;
                catRenaming.IsEditing = false;
                _isDirty = true;
            }
        }

        if (catEditing != null)
        {
            // ReSharper disable once ForCanBeConvertedToForeach
            for (var c = 0; c < _pool._categories.Count; c++)
            {
                var cat = _pool._categories[c];
                // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                if (catEditing == cat)
                {
                    cat.IsEditing = true;
                }
                else
                {
                    cat.IsEditing = false;
                }

                _isDirty = true;
            }
        }

        if (itemToRemove != null)
        {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "remove Pool Item");
            _pool.poolItems.Remove(itemToRemove);
        }
        if (itemToClone != null)
        {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "clone Pool Item");
            var newItem = itemToClone.Clone();

            var oldIndex = _pool.poolItems.IndexOf(itemToClone);

            _pool.poolItems.Insert(oldIndex, newItem);
        }

        if (indexToInsertAt.HasValue)
        {
            UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _pool, "insert Pool Item");
            _pool.poolItems.Insert(indexToInsertAt.Value, new PoolBossItem {
                categoryName = selectedCategory.CatName
            });
        }

        if (GUI.changed || _isDirty)
        {
            EditorUtility.SetDirty(target);     // or it won't save the data!!
        }

        //DrawDefaultInspector();
    }