Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        /// <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);
        }
        /// <summary>
        /// Destroys the projectile on impact and finds objects in range to
        ///	affect if they share the same tag as target.
        /// </summary>
        public void DetonateProjectile()
        {
            // Prevent being run more than once in a frame where it has already
            //   been destroyed.
            if (!this.gameObject.activeInHierarchy)
            {
                return;
            }

            // Build a new list of targets depending on the options used
            var targetList = new TargetList();

            if (this.areaHit)
            {
                // This is turned back off OnDisable() (base class)
                this.perimeter.enabled = true;

                targetList.AddRange(this.targets); // Add all targets in range
            }
            else
            {
                if (this.target != Target.Null)
                {
                    targetList.Add(this.target); // Add projectile target
                }
            }

            if (this.debugLevel > DEBUG_LEVELS.Off)
            {
                string msg = string.Format("Detonating with targets: {0}", targetList);
                Debug.Log(string.Format("Projectile ({0}): {1}", this.name, msg));
            }

            // Create a new list of targets which have this target tracker reference.
            //   This is for output so targets which are handled at all by this Projectile
            //   are stamped with a reference.
            var    targetCopies = new TargetList();
            Target target;

            foreach (Target inTarget in targetList)
            {
                if (inTarget == Target.Null)
                {
                    continue;
                }

                // Can't edit a struct in a foreach loop, so need to copy and store
                target            = new Target(inTarget);
                target.projectile = this;  // Add reference. null before t
                targetCopies.Add(target);

                switch (this.notifyTargets)
                {
                case NOTIFY_TARGET_OPTIONS.Direct:
                    target.targetable.OnHit(this.effectsOnTarget, target, this.collider);
                    break;
                }

                // Just for debug. Show a gizmo line when firing
                if (this.debugLevel > DEBUG_LEVELS.Off)
                {
                    Debug.DrawLine
                    (
                        this.xform.position,
                        target.transform.position,
                        Color.red
                    );
                }
            }

            switch (this.notifyTargets)
            {
            case NOTIFY_TARGET_OPTIONS.Direct:
                this.SpawnDetonatorPrefab(false);
                break;

            case NOTIFY_TARGET_OPTIONS.PassToDetonator:
                this.SpawnDetonatorPrefab(true);
                break;
            }


            // Trigger delegates
            if (this.OnDetonationDelegates != null)
            {
                this.OnDetonationDelegates(targetCopies);
            }

            // Clean-up in case this instance is used in a pooling system like PoolManager
            this.target = Target.Null;

            InstanceManager.Despawn(this.transform);
        }