Exemplo n.º 1
0
        /// <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
        }
Exemplo n.º 2
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);
        }