protected IEnumerator ListenToDespawn(AudioSource src) { // Safer to wait a frame before testing if playing. yield return(null); while (src.isPlaying) { yield return(null); } InstanceManager.Despawn(this.poolName, src.transform); }
protected IEnumerator ListenToDespawn(ParticleSystem emitter) { // Wait for the delay time to complete // Waiting the extra frame seems to be more stable and means at least one // frame will always pass yield return(new WaitForSeconds(emitter.startDelay + 0.25f)); while (emitter.IsAlive(true)) { if (!emitter.gameObject.activeInHierarchy) { emitter.Clear(true); yield break; // Do nothing, already despawned. Quit. } yield return(null); } // Turn off emit before despawning InstanceManager.Despawn(this.poolName, emitter.transform); }
/// <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); }