/// <summary> /// Moves a SwarmItem from the active list to the inactive list and changes its parent transform /// </summary> /// <param name="item">The SwarmItem to deactivate</param> public virtual void DeactiveItem(SwarmItem item) { if (item == null) { throw new Exception("SwarmItem can't be null"); } // remove from the active linked list _prefabItemLists[item.PrefabIndex].activeItems.Remove(item); // push onto the inactive stack _prefabItemLists[item.PrefabIndex].inactiveItems.Push(item); // move the item to the inactive parent transform. // this is mainly just for visual reference in the editor SetItemParentTransform(item, _inactiveParentTransform); if (debugEvents) { Debug.Log("Deactivated " + item.name + " at frame: " + Time.frameCount); } // if the prune timer is not currently running and we actually want to prune if (_prefabItemLists[item.PrefabIndex].inactivePruneTimeLeft == 0 && itemPrefabs[item.PrefabIndex].inactivePrunePercentage > 0) { // if the inactive item count exceeds the threshold if (((float)(_prefabItemLists[item.PrefabIndex].inactiveItems.Count) / (float)_prefabItemLists[item.PrefabIndex].ItemCount) >= itemPrefabs[item.PrefabIndex].inactiveThreshold) { if (debugEvents) { Debug.Log("Inactive threshold [" + (itemPrefabs[item.PrefabIndex].inactiveThreshold * 100) + "%] reached for " + itemPrefabs[item.PrefabIndex].prefab.name + " list. Starting prune timer [" + itemPrefabs[item.PrefabIndex].inactivePruneTimer + " seconds] at frame: " + Time.frameCount); } // if the prune timer is set to expire immediately if (itemPrefabs[item.PrefabIndex].inactivePruneTimer == 0) { // don't wait for a countdown, just prune immediately PruneList(item.PrefabIndex, itemPrefabs[item.PrefabIndex].inactivePrunePercentage); } else { // turn the prune timer on _prefabItemLists[item.PrefabIndex].inactivePruneTimeLeft = itemPrefabs[item.PrefabIndex].inactivePruneTimer; } } } item.gameObject.SetActive(false); }
/** * Preloads a certain prefab to a certain amount */ public void Preload(int itemPrefabIndex, int preloadCount) { if (_prefabItemLists[itemPrefabIndex].inactiveItems.Count >= preloadCount) { // there are already enough inactive items // no need to proceed return; } // we lazy initialize because not all item managers needs preloading if (this.preloadList == null) { this.preloadList = new SimpleList <SwarmItem>(); } this.preloadList.Clear(); // note here that we only preload the remaining amount // to preload, we need to passes // first to activate items // then another pass to kill them // we can't simple Activate() then Kill() because it will just reuse the previously killed unit int remaining = preloadCount - _prefabItemLists[itemPrefabIndex].inactiveItems.Count; for (int i = 0; i < remaining; ++i) { SwarmItem item = ActivateItem(itemPrefabIndex); this.preloadList.Add(item); // add temporarily so we could kill later } for (int i = 0; i < this.preloadList.Count; ++i) { this.preloadList[i].Kill(); } this.preloadList.Clear(); }
/// <summary> /// Moves a SwarmItem to the active or inactive transforms. /// This is mainly used a visual aid in the editor to see which items are active or inactive /// </summary> /// <param name="item">The SwarmItem to move</param> /// <param name="parentTransform">The parent transform to move to</param> private void SetItemParentTransform(SwarmItem item, Transform parentTransform) { if (item == null) { throw new Exception("item can't be null"); } if (parentTransform == null) { throw new Exception("parentTransform can't be null"); } // reparent this item's transform item.ThisTransform.parent = parentTransform; // reset the position, rotation, and scale to unit values item.ThisTransform.localPosition = Vector3.zero; item.ThisTransform.localRotation = Quaternion.identity; item.ThisTransform.localScale = Vector3.one; // if the position, rotation, or scale need to be changed after reparenting, do it in the // item's OnSetParentTransform method item.OnSetParentTransform(); }
/// <summary> /// Activates a SwarmItem base on the prefab index (type). If there is an inactive item, /// the manager will recycle that first, otherwise it will instantiate a new item /// </summary> /// <param name="itemPrefabIndex">The index of the prefab to use (type of SwarmItem)</param> /// <returns>Returns the newly created SwarmItem</returns> public virtual SwarmItem ActivateItem(int itemPrefabIndex) { // we have exceeded the maximum item count for this prefab (if a limit is set) // so return nothing if (_prefabItemLists[itemPrefabIndex].activeItems.Count == itemPrefabs[itemPrefabIndex].maxItemCount && itemPrefabs[itemPrefabIndex].maxItemCount > 0) { if (debugEvents) { Debug.Log("Could not activate item because the count [" + _prefabItemLists[itemPrefabIndex].activeItems.Count + "] is at the maximum number for this item type at frame: " + Time.frameCount); } return(null); } SwarmItem localItem = null; // [Marnel] HACK!!! // search for a non null item while there are inactive items // for some reason, the entry in the inactiveItems becomes null while (localItem == null && _prefabItemLists[itemPrefabIndex].inactiveItems.Count > 0) { localItem = _prefabItemLists[itemPrefabIndex].inactiveItems.Pop(); } if (localItem == null) { // no item to recycle // instantiate item localItem = InstantiateItem(itemPrefabIndex); // queue to the end of the active list _prefabItemLists[itemPrefabIndex].activeItems.AddLast(localItem); if (debugEvents) { Debug.Log("Instantiated a new item " + _go.name + " at frame: " + Time.frameCount); } } else { // there is an inactive item so we recycle it _prefabItemLists[itemPrefabIndex].activeItems.AddLast(localItem); if (debugEvents) { Debug.Log("Recycled item " + localItem.name + " at frame: " + Time.frameCount); } } // move the item to active parent transform. // this is mainly just for visual reference in the editor SetItemParentTransform(localItem, _activeParentTransform); // set the state to active localItem.State = SwarmItem.STATE.Active; // if the prune timer is runnning if (_prefabItemLists[itemPrefabIndex].inactivePruneTimeLeft > 0) { // if the inactive item count dropped below the threshold if (((float)_prefabItemLists[itemPrefabIndex].inactiveItems.Count / (float)_prefabItemLists[itemPrefabIndex].ItemCount) < itemPrefabs[itemPrefabIndex].inactiveThreshold) { if (debugEvents) { Debug.Log("Dropped below inactive threshold [" + (itemPrefabs[itemPrefabIndex].inactiveThreshold * 100) + "%] for " + itemPrefabs[itemPrefabIndex].prefab.name + " list before timer expired. Stopping prune timer at frame: " + Time.frameCount); } // turn the prune timer off _prefabItemLists[itemPrefabIndex].inactivePruneTimeLeft = 0; } } return(localItem); }
/// <summary> /// Moves a SwarmItem to the active or inactive transforms. /// This is mainly used a visual aid in the editor to see which items are active or inactive /// </summary> /// <param name="item">The SwarmItem to move</param> /// <param name="parentTransform">The parent transform to move to</param> private void SetItemParentTransform(SwarmItem item, Transform parentTransform) { // reparent this item's transform item.ThisTransform.parent = parentTransform; // reset the position, rotation, and scale to unit values item.ThisTransform.localPosition = Vector3.zero; item.ThisTransform.localRotation = Quaternion.identity; item.ThisTransform.localScale = Vector3.one; // if the position, rotation, or scale need to be changed after reparenting, do it in the // item's OnSetParentTransform method item.OnSetParentTransform(); }
/// <summary> /// Moves a SwarmItem from the active list to the inactive list and changes its parent transform /// </summary> /// <param name="item">The SwarmItem to deactivate</param> public virtual void DeactiveItem(SwarmItem item) { // remove from the active linked list _prefabItemLists[item.PrefabIndex].activeItems.Remove(item); // push onto the inactive stack _prefabItemLists[item.PrefabIndex].inactiveItems.Push(item); // move the item to the inactive parent transform. // this is mainly just for visual reference in the editor SetItemParentTransform(item, _inactiveParentTransform); if (DebugEvents) Debug.Log("Deactivated " + item.name + " at frame: " + Time.frameCount); // if the prune timer is not currently running and we actually want to prune if (_prefabItemLists[item.PrefabIndex].inactivePruneTimeLeft == 0 && itemPrefabs[item.PrefabIndex].inactivePrunePercentage > 0) { // if the inactive item count exceeds the threshold if (((float)(_prefabItemLists[item.PrefabIndex].inactiveItems.Count) / (float)_prefabItemLists[item.PrefabIndex].itemCount) >= itemPrefabs[item.PrefabIndex].inactiveThreshold) { if (DebugEvents) Debug.Log("Inactive threshold [" + (itemPrefabs[item.PrefabIndex].inactiveThreshold * 100) + "%] reached for " + itemPrefabs[item.PrefabIndex].prefab.name + " list. Starting prune timer [" + itemPrefabs[item.PrefabIndex].inactivePruneTimer + " seconds] at frame: " + Time.frameCount); // if the prune timer is set to expire immediately if (itemPrefabs[item.PrefabIndex].inactivePruneTimer == 0) { // don't wait for a countdown, just prune immediately PruneList(item.PrefabIndex, itemPrefabs[item.PrefabIndex].inactivePrunePercentage); } else { // turn the prune timer on _prefabItemLists[item.PrefabIndex].inactivePruneTimeLeft = itemPrefabs[item.PrefabIndex].inactivePruneTimer; } } } }
/// <summary> /// Activates a SwarmItem base on the prefab index (type). If there is an inactive item, /// the manager will recycle that first, otherwise it will instantiate a new item /// </summary> /// <param name="itemPrefabIndex">The index of the prefab to use (type of SwarmItem)</param> /// <returns>Returns the newly created SwarmItem</returns> public virtual SwarmItem ActivateItem(int itemPrefabIndex) { // we have exceeded the maximum item count for this prefab (if a limit is set) // so return nothing if (_prefabItemLists[itemPrefabIndex].activeItems.Count == itemPrefabs[itemPrefabIndex].maxItemCount && itemPrefabs[itemPrefabIndex].maxItemCount > 0) { if (DebugEvents) Debug.Log("Could not activate item because the count [" + _prefabItemLists[itemPrefabIndex].activeItems.Count + "] is at the maximum number for this item type at frame: " + Time.frameCount); return null; } if (_prefabItemLists[itemPrefabIndex].inactiveItems.Count > 0) { // there is an inactive item so we recycle it // pop off the inactive stack _item = _prefabItemLists[itemPrefabIndex].inactiveItems.Pop(); // queue to the end of the active list _prefabItemLists[itemPrefabIndex].activeItems.AddLast(_item); if (DebugEvents) Debug.Log("Recycled item " + _item.name + " at frame: " + Time.frameCount); } else { // no inactive item availble, so create a new one // instantiate item _item = InstantiateItem(itemPrefabIndex); // queue to the end of the active list _prefabItemLists[itemPrefabIndex].activeItems.AddLast(_item); if (DebugEvents) Debug.Log("Instantiated a new item " + _go.name + " at frame: " + Time.frameCount); } // move the item to active parent transform. // this is mainly just for visual reference in the editor SetItemParentTransform(_item, _activeParentTransform); // set the state to active _item.State = SwarmItem.STATE.Active; // if the prune timer is runnning if (_prefabItemLists[itemPrefabIndex].inactivePruneTimeLeft > 0) { // if the inactive item count dropped below the threshold if (((float)_prefabItemLists[itemPrefabIndex].inactiveItems.Count / (float)_prefabItemLists[itemPrefabIndex].itemCount) < itemPrefabs[itemPrefabIndex].inactiveThreshold) { if (DebugEvents) Debug.Log("Dropped below inactive threshold [" + (itemPrefabs[itemPrefabIndex].inactiveThreshold * 100) + "%] for " + itemPrefabs[itemPrefabIndex].prefab.name + " list before timer expired. Stopping prune timer at frame: " + Time.frameCount); // turn the prune timer off _prefabItemLists[itemPrefabIndex].inactivePruneTimeLeft = 0; } } return _item; }
/** * Requests for a prefab instance using the specified index */ public GameObject Request(int prefabIndex) { SwarmItem item = itemManager.ActivateItem(prefabIndex); return(item.gameObject); }
void Awake() { this.swarm = GetComponent <SwarmItem>(); Assertion.AssertNotNull(this.swarm); }