/// <summary> /// Creates a new instance. /// /// If PoolManager is installed and the pre-proccessor directive is /// uncommented at the top of TargetTracker.cs, this will use PoolManager to /// pool ammo instances. /// /// If the pool doesn't exist before this is used, it will be created. /// /// Otherwise, Unity's Object.Instantiate() is used. /// </summary> /// <param name="prefab">The prefab to spawn an instance from</param> /// <param name="pos">The position to spawn the instance</param> /// <param name="rot">The rotation of the new instance</param> /// <returns></returns> public static Transform Spawn(string poolName, Transform prefab, Vector3 pos, Quaternion rot) { #if POOLMANAGER_INSTALLED || USE_OTHER_POOLING if (poolName == "") // Overload use of poolName to toggle pooling { return((Transform)Object.Instantiate(prefab, pos, rot)); } #endif #if POOLMANAGER_INSTALLED // If the pool doesn't exist, it will be created before use if (!PoolManager.Pools.ContainsKey(poolName)) { (new GameObject(poolName)).AddComponent <SpawnPool>(); } return(PoolManager.Pools[poolName].Spawn(prefab, pos, rot)); #elif USE_OTHER_POOLING InstanceManager.OnSpawnDelegates(poolName, prefab, pos, rot); #else return((Transform)Object.Instantiate(prefab, pos, rot)); #endif }
/// <summary> /// Despawns this EventTrigger on impact, timeout or sleep (depending on options) /// and notifies objects in range with EventInfo. /// </summary> public virtual IEnumerator Fire() { // Prevent being run more than once in a frame where it has already // been despawned. if (!this.gameObject.activeInHierarchy) { yield break; } if (this.duration > 0) { this.range = this.startRange; } // This TargetList collects targets that are notified below the this.detectedTargetsCache.Clear(); // Prevent the Area event from notifying targets in this.OnTargetDetectedNotify() this.blockNotifications = true; if (this.areaHit) { // This is turned back off OnDisable() (base class) // Also triggers OnDetected via an event to handle all targets found when enabled! this.setAreaColliderEnabled(true); // Need to wait a frame to let Unity send the physics Enter events to the Area. // Wait for next frame to begin to be sure targets have been propegated // This also makes this loop easier to manage. //yield return new WaitForFixedUpdate(); // This seems logical but doesn't work yield return(null); } else { this.OnNewTargetHandler(this, this.target); } // Let future detections notifiy targets (in case duration is != 0) // This HAS to be bellow the yield or it will only work sometimes. this.blockNotifications = false; // Trigger delegates BEFORE processing notifications in case a delegate modifies the // list of targets if (this.OnFireDelegates != null) { this.OnFireDelegates(this.detectedTargetsCache); } foreach (Target processedTarget in this.detectedTargetsCache) { this.HandleNotifyTarget(processedTarget); } this.detectedTargetsCache.Clear(); // Just to be clean. if (this.notifyTargets == NOTIFY_TARGET_OPTIONS.PassInfoToEventTrigger) { this.SpawnOnFirePrefab(true); } // Hnadle keeping this EventTrigger alive and the range change over time. // Any new targets from this point on will be handled by OnNewDetected, which // is triggered by AreaTargetTracker logic. if (this.duration != 0) { // Determine which while() statement is needed. One that runs out after a // certain duration or one that runs forever while this component is active. if (this.duration < 0) { while (true) { // UPDATE EVENT if (this.OnFireUpdateDelegates != null) { this.OnFireUpdateDelegates(-1); } //yield return new WaitForFixedUpdate(); // Seems logical but doesn't work. yield return(null); } } else { float timer = 0; float progress = 0; // Normalized value that will be 0-1 while (progress < 1) { // UPDATE EVENT if (this.OnFireUpdateDelegates != null) { this.OnFireUpdateDelegates(progress); } timer += Time.deltaTime; progress = timer / this.duration; this.range = this._endRange * progress; //yield return new WaitForFixedUpdate(); // Seems logical but doesn't work. yield return(null); } this.range = this._endRange; // for percision } } // // Handle despoawn... // // Do this check again due to duration. // Prevent being run more than once in a frame where it has already // been despawned. if (!this.gameObject.activeInHierarchy) { yield break; } InstanceManager.Despawn(this.poolName, this.transform); yield return(null); }