Beispiel #1
0
        /// <summary>
        /// The effect has been started.
        /// </summary>
        protected override void EffectStarted()
        {
            base.EffectStarted();

            var clip = m_AudioClipSet.PlayAudioClip(m_GameObject);

            AudioManager.Play(m_GameObject, clip);

            Scheduler.ScheduleFixed(clip.length, StopEffect);
        }
Beispiel #2
0
        /// <summary>
        /// The effect has been started.
        /// </summary>
        protected override void EffectStarted()
        {
            base.EffectStarted();

            var audioSource = m_AudioClipSet.PlayAudioClip(m_GameObject).AudioSource;

            if (audioSource != null)
            {
                SchedulerBase.ScheduleFixed(audioSource.clip.length, StopEffect);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Adds amount to health and then to the shield if there is still an amount remaining. Will not go over the maximum health or shield value.
        /// </summary>
        /// <param name="amount">The amount of health or shield to add.</param>
        /// <returns>True if the object was healed.</returns>
        public virtual bool Heal(float amount)
        {
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_NetworkInfo != null && m_NetworkInfo.IsLocalPlayer())
            {
                m_NetworkHealthMonitor.Heal(amount);
            }
#endif

            var healAmount = 0f;

            // Contribute the amount of the health first.
            if (m_HealthAttribute != null && m_HealthAttribute.Value < m_HealthAttribute.MaxValue)
            {
                var healthAmount = Mathf.Min(amount, m_HealthAttribute.MaxValue - m_HealthAttribute.Value);
                amount -= healthAmount;
                m_HealthAttribute.Value += healthAmount;
                healAmount += healthAmount;
            }

            // Add any remaining amount to the shield.
            if (m_ShieldAttribute != null && amount > 0 && m_ShieldAttribute.Value < m_ShieldAttribute.MaxValue)
            {
                var shieldAmount = Mathf.Min(amount, m_ShieldAttribute.MaxValue - m_ShieldAttribute.Value);
                m_ShieldAttribute.Value += shieldAmount;
                healAmount += shieldAmount;
            }

            // Don't play any effects if the object wasn't healed.
            if (healAmount == 0)
            {
                return(false);
            }

            // Play any heal audio.
            m_HealAudioClipSet.PlayAudioClip(m_GameObject);

            EventHandler.ExecuteEvent <float>(m_GameObject, "OnHealthHeal", healAmount);
            if (m_OnHealEvent != null)
            {
                m_OnHealEvent.Invoke(healAmount);
            }
            if (m_DamagePopupManager != null)
            {
                m_DamagePopupManager.OpenHealPopup(m_Transform.position, amount);
            }

            return(true);
        }
Beispiel #4
0
        /// <summary>
        /// The ability should perform a airborne jump.
        /// </summary>
        private void OnAirborneJump()
        {
            if (m_MaxAirborneJumpCount != -1 && m_AirborneJumpCount >= m_MaxAirborneJumpCount)
            {
                return;
            }

            // Reset the accumulated gravity to allow for a full airborne jump.
            m_CharacterLocomotion.GravityAmount = 0;
            AddForce(m_CharacterLocomotion.Up * m_AirborneJumpForce, m_AirborneJumpFrames, false, true);
            m_AirborneJumpCount++;
            m_JumpTime = Time.time;
            // The repeated jump may be applied just as the fall ability is about to start. Prevent the jump ability from stopping immediately after starting a repeated jump.
            m_AirborneJumpApplied = true;
            m_AirborneJumpAudioClipSet.PlayAudioClip(m_GameObject);
            SetAbilityIntDataParameter(AbilityIntData);
        }
Beispiel #5
0
        /// <summary>
        /// The other collider has entered the trigger.
        /// </summary>
        /// <param name="other">The collider which entered the trigger.</param>
        private void OnTriggerEnter(Collider other)
        {
            if (!MathUtility.InLayerMask(other.gameObject.layer, m_LayerMask))
            {
                return;
            }

            StateBehavior stateBehavior;

            if ((m_RequireCharacter && (stateBehavior = other.GetComponentInParent <Character.UltimateCharacterLocomotion>()) != null) ||
                (!m_RequireCharacter && (stateBehavior = other.GetComponentInParent <StateBehavior>()) != null))
            {
                m_ActivateStateEvent = SchedulerBase.Schedule(m_Delay, ChangeState, stateBehavior.gameObject, true);

                m_ActivateAudioClipSet.PlayAudioClip(null);
            }
        }
        /// <summary>
        /// Initializes the object with the specified velocity and torque.
        /// </summary>
        /// <param name="velocity">The starting velocity.</param>
        /// <param name="torque">The starting torque.</param>
        /// <param name="originator">The object that instantiated the trajectory object.</param>
        /// <param name="originatorCollisionCheck">Should a collision check against the originator be performed?</param>
        /// <param name="defaultNormalizedGravity">The normalized gravity direction if a character isn't specified for the originator.</param>
        public virtual void Initialize(Vector3 velocity, Vector3 torque, GameObject originator, bool originatorCollisionCheck, Vector3 defaultNormalizedGravity)
        {
            InitializeComponentReferences();

            m_Velocity = velocity / m_Mass * m_StartVelocityMultiplier;
            m_Torque   = torque;
            SetOriginator(originator, defaultNormalizedGravity);
            m_Gravity = m_NormalizedGravity * m_GravityMagnitude;
            m_OriginatorCollisionCheck = m_Originator != null;

            m_Platform        = null;
            m_MovementSettled = m_RotationSettled = false;
            m_InCollision     = false;
            m_Collided        = false;
            if (m_Collider != null)
            {
                m_Collider.enabled = true;
            }
            m_ActiveAudioClipSet.PlayAudioClip(m_GameObject, 0, true);
            enabled = true;

            // Set the layer to prevent the current object from getting in the way of the casts.
            var previousLayer = m_GameObject.layer;

            m_GameObject.layer = LayerManager.IgnoreRaycast;

            // The object could start in a collision state.
            if (originatorCollisionCheck && OverlapCast(m_Transform.position, m_Transform.rotation))
            {
                OnCollision(null);
                if (m_CollisionMode == CollisionMode.Collide)
                {
                    m_MovementSettled = m_RotationSettled = true;
                }
                else if (m_CollisionMode != CollisionMode.Ignore)     // Reflect and Random Reflection.
                // Update the velocity to the reflection direction. Use the originator's forward direction as the normal because the actual collision point is not determined.
                {
                    m_Velocity = Vector3.Reflect(m_Velocity, -m_OriginatorTransform.forward) * m_ReflectMultiplier;
                }
            }

            m_GameObject.layer = previousLayer;
        }
Beispiel #7
0
        /// <summary>
        /// The ability should perform a repeated jump.
        /// </summary>
        private void OnRepeatedJump()
        {
            if (m_MaxRepeatedJumpCount != -1 && m_RepeatedJumpCount >= m_MaxRepeatedJumpCount)
            {
                return;
            }

            if (m_JumpTime == -1 || m_JumpTime + m_RecurrenceDelay > Time.time)
            {
                return;
            }

            AddForce(m_CharacterLocomotion.Up * m_RepeatedJumpForce, m_RepeatedJumpFrames, false, true);
            m_RepeatedJumpCount++;
            m_JumpTime = Time.time;
            // The repeated jump may be applied just as the fall ability is about to start. Prevent the jump ability from stopping immediately after starting a repeated jump.
            m_RepeatedJumpApplied = true;
            m_RepeatedJumpAudioClipSet.PlayAudioClip(m_GameObject);
            m_CharacterLocomotion.UpdateAbilityAnimatorParameters();
        }
Beispiel #8
0
        /// <summary>
        /// The object has been picked up.
        /// </summary>
        /// <param name="pickedUpBy">A reference to the object that picked up the object.</param>
        protected virtual void ObjectPickedUp(GameObject pickedUpBy)
        {
            // The object may not have been instantiated within the scene.
            if (m_GameObject == null)
            {
                return;
            }

            m_IsDepleted = true;

            // Send an event notifying of the pickup.
            EventHandler.ExecuteEvent(pickedUpBy, "OnObjectPickedUp", this);

            // Optionally play a pickup sound if the object picking up the item is attached to a camera.
            // A null GameObject indicates that the clip will play from the AudioManager.
            var camera = Utility.UnityEngineUtility.FindCamera(pickedUpBy);

            if (camera != null)
            {
                m_PickupAudioClipSet.PlayAudioClip(null);
            }

            if (ObjectPool.InstantiatedWithPool(m_GameObject))
            {
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
                if (NetworkObjectPool.IsNetworkActive())
                {
                    NetworkObjectPool.Destroy(m_GameObject);
                    return;
                }
#endif
                ObjectPool.Destroy(m_GameObject);
            }
            else
            {
                // Deactivate the pickup for now. It can appear again if a Respawner component is attached to the GameObject.
                m_GameObject.SetActive(false);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Does the respawn by setting the position and rotation to the specified values.
        /// Enable the GameObject and let all of the listening objects know that the object has been respawned.
        /// </summary>
        /// <param name="position">The respawn position.</param>
        /// <param name="rotation">The respawn rotation.</param>
        /// <param name="transformChange">Was the position or rotation changed?</param>
        public virtual void Respawn(Vector3 position, Quaternion rotation, bool transformChange)
        {
            // Send a pre-respawn event so abilities can stop if they should no longer be active.
            EventHandler.ExecuteEvent(m_GameObject, "OnWillRespawn");

            if (transformChange)
            {
                // Characters require a specific setter for the position and rotation.
                if (m_CharacterLocomotion != null)
                {
                    m_CharacterLocomotion.SetPositionAndRotation(position, rotation);
                }
                else
                {
                    m_Transform.position = position;
                    m_Transform.rotation = rotation;
                }
            }

            m_GameObject.SetActive(true);

            // Play any respawn audio.
            m_RespawnAudioClipSet.PlayAudioClip(m_GameObject);

            EventHandler.ExecuteEvent(m_GameObject, "OnRespawn");
            if (m_OnRespawnEvent != null)
            {
                m_OnRespawnEvent.Invoke();
            }

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_NetworkInfo != null && m_NetworkInfo.IsLocalPlayer())
            {
                m_NetworkRespawnerMonitor.Respawn(position, rotation, transformChange);
            }
#endif
        }
Beispiel #10
0
        /// <summary>
        /// Do the explosion.
        /// </summary>
        /// <param name="damageAmount">The amount of damage to apply to the hit objects.</param>
        /// <param name="impactForce">The amount of force to apply to the hit object.</param>
        /// <param name="impactForceFrames">The number of frames to add the force to.</param>
        /// <param name="originator">The originator of the object.</param>
        public void Explode(float damageAmount, float impactForce, int impactForceFrames, GameObject originator)
        {
            Health       health            = null;
            Rigidbody    colliderRigidbody = null;
            IForceObject forceObject       = null;
            var          hitCount          = Physics.OverlapSphereNonAlloc(m_Transform.position, m_Radius, m_CollidersHit, m_ImpactLayers, QueryTriggerInteraction.Ignore);

#if UNITY_EDITOR
            if (hitCount == m_MaxCollisionCount)
            {
                Debug.LogWarning("Warning: The maximum number of colliders have been hit by " + m_GameObject.name + ". Consider increasing the Max Collision Count value.");
            }
#endif
            for (int i = 0; i < hitCount; ++i)
            {
                // A GameObject can contain multiple colliders. Prevent the explosion from occurring on the same GameObject multiple times.
                if (m_ObjectExplosions.Contains(m_CollidersHit[i].gameObject))
                {
                    continue;
                }
                m_ObjectExplosions.Add(m_CollidersHit[i].gameObject);
                // The base character GameObject should only be checked once.
                if ((forceObject = m_CollidersHit[i].gameObject.GetCachedParentComponent <IForceObject>()) != null)
                {
                    if (m_ObjectExplosions.Contains(forceObject))
                    {
                        continue;
                    }
                    m_ObjectExplosions.Add(forceObject);
                }

                // OverlapSphere can return objects that are in a different room. Perform a cast to ensure the object is within the explosion range.
                if (m_LineOfSight)
                {
                    // Add a slight vertical offset to prevent a floor collider from getting in the way of the cast.
                    var position  = m_Transform.TransformPoint(0, 0.1f, 0);
                    var direction = m_CollidersHit[i].transform.position - position;
                    if (Physics.Raycast(position - direction.normalized * 0.1f, direction, out m_RaycastHit, direction.magnitude, m_ImpactLayers, QueryTriggerInteraction.Ignore) &&
                        !(m_RaycastHit.transform.IsChildOf(m_CollidersHit[i].transform)
#if FIRST_PERSON_CONTROLLER
                          // The cast should not hit any colliders who are a child of the camera.
                          || m_RaycastHit.transform.gameObject.GetCachedParentComponent <FirstPersonController.Character.FirstPersonObjects>() != null
#endif
                          ))
                    {
                        // If the collider is part of a character then ensure the head can't be hit.
                        var parentAnimator = m_CollidersHit[i].transform.gameObject.GetCachedParentComponent <Animator>();
                        if (parentAnimator != null && parentAnimator.isHuman)
                        {
                            var head = parentAnimator.GetBoneTransform(HumanBodyBones.Head);
                            direction = head.position - position;
                            if (Physics.Raycast(position, direction, out m_RaycastHit, direction.magnitude, m_ImpactLayers, QueryTriggerInteraction.Ignore) &&
                                !m_RaycastHit.transform.IsChildOf(m_CollidersHit[i].transform) && !m_CollidersHit[i].transform.IsChildOf(m_RaycastHit.transform) &&
                                m_RaycastHit.transform.IsChildOf(m_Transform)
#if FIRST_PERSON_CONTROLLER
                                // The cast should not hit any colliders who are a child of the camera.
                                && m_RaycastHit.transform.gameObject.GetCachedParentComponent <FirstPersonController.Character.FirstPersonObjects>() == null
#endif
                                )
                            {
                                continue;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                }

                // The shield can absorb some (or none) of the damage from the explosion.
                var hitDamageAmount = damageAmount;
#if ULTIMATE_CHARACTER_CONTROLLER_MELEE
                ShieldCollider shieldCollider;
                if ((shieldCollider = m_CollidersHit[i].transform.gameObject.GetCachedComponent <ShieldCollider>()) != null)
                {
                    hitDamageAmount = shieldCollider.Shield.Damage(this, hitDamageAmount);
                }
#endif

                // ClosestPoint only works with a subset of collider types.
                Vector3 closestPoint;
                if (m_CollidersHit[i] is BoxCollider || m_CollidersHit[i] is SphereCollider || m_CollidersHit[i] is CapsuleCollider || (m_CollidersHit[i] is MeshCollider && (m_CollidersHit[i] as MeshCollider).convex))
                {
                    closestPoint = m_CollidersHit[i].ClosestPoint(m_Transform.position);
                }
                else
                {
                    closestPoint = m_CollidersHit[i].ClosestPointOnBounds(m_Transform.position);
                }
                var hitDirection = closestPoint - m_Transform.position;

                // Allow a custom event to be received.
                EventHandler.ExecuteEvent <float, Vector3, Vector3, GameObject, object, Collider>(m_CollidersHit[i].transform.gameObject, "OnObjectImpact", hitDamageAmount, closestPoint, hitDirection * m_ImpactForce, originator, this, m_CollidersHit[i]);
                if (m_OnImpactEvent != null)
                {
                    m_OnImpactEvent.Invoke(hitDamageAmount, closestPoint, hitDirection * m_ImpactForce, originator);
                }

                // If the shield didn't absorb all of the damage then it should be applied to the character.
                if (hitDamageAmount > 0)
                {
                    // If the Health component exists it will apply an explosive force to the character/character in addition to deducting the health.
                    // Otherwise just apply the force to the character/rigidbody.
                    if ((health = m_CollidersHit[i].gameObject.GetCachedParentComponent <Health>()) != null)
                    {
                        // The further out the collider is, the less it is damaged.
                        var damageModifier = Mathf.Max(1 - (hitDirection.magnitude / m_Radius), 0.01f);
                        health.Damage(hitDamageAmount * damageModifier, m_Transform.position, hitDirection.normalized, impactForce * damageModifier, impactForceFrames, m_Radius, originator, this, null);
                    }
                    else if (forceObject != null)
                    {
                        var damageModifier = Mathf.Max(1 - (hitDirection.magnitude / m_Radius), 0.01f);
                        forceObject.AddForce(hitDirection.normalized * impactForce * damageModifier);
                    }
                    else if ((colliderRigidbody = m_CollidersHit[i].gameObject.GetCachedComponent <Rigidbody>()) != null)
                    {
                        colliderRigidbody.AddExplosionForce(impactForce * MathUtility.RigidbodyForceMultiplier, m_Transform.position, m_Radius);
                    }
                }
            }
            m_ObjectExplosions.Clear();

            // An audio clip can play when the object explodes.
            m_ExplosionAudioClipSet.PlayAudioClip(m_GameObject);

            Scheduler.Schedule(m_Lifespan, Destroy);
        }
Beispiel #11
0
        /// <summary>
        /// The object has taken been damaged.
        /// </summary>
        /// <param name="amount">The amount of damage taken.</param>
        /// <param name="position">The position of the damage.</param>
        /// <param name="direction">The direction that the object took damage from.</param>
        /// <param name="forceMagnitude">The magnitude of the force that is applied to the object.</param>
        /// <param name="frames">The number of frames to add the force to.</param>
        /// <param name="radius">The radius of the explosive damage. If 0 then a non-explosive force will be used.</param>
        /// <param name="attacker">The GameObject that did the damage.</param>
        /// <param name="attackerObject">The object that did the damage.</param>
        /// <param name="hitCollider">The Collider that was hit.</param>
        public virtual void OnDamage(float amount, Vector3 position, Vector3 direction, float forceMagnitude, int frames, float radius, GameObject attacker, object attackerObject, Collider hitCollider)
        {
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_NetworkInfo != null && m_NetworkInfo.IsLocalPlayer())
            {
                m_NetworkHealthMonitor.OnDamage(amount, position, direction, forceMagnitude, frames, radius, attacker, hitCollider);
            }
#endif

            // Add a multiplier if a particular collider was hit. Do not apply a multiplier if the damage is applied through a radius because multiple
            // collider are hit.
            if (radius == 0 && direction != Vector3.zero && hitCollider != null)
            {
                Hitbox hitbox;
                if (m_ColliderHitboxMap != null && m_ColliderHitboxMap.Count > 0)
                {
                    if (m_ColliderHitboxMap.TryGetValue(hitCollider, out hitbox))
                    {
                        amount *= hitbox.DamageMultiplier;
                    }
                    else
                    {
                        // The main collider may be overlapping child hitbox colliders. Perform one more raycast to ensure a hitbox collider shouldn't be hit.
                        float distance = 0.2f;
                        if (hitCollider is CapsuleCollider)
                        {
                            distance = (hitCollider as CapsuleCollider).radius;
                        }
                        else if (hitCollider is SphereCollider)
                        {
                            distance = (hitCollider as SphereCollider).radius;
                        }

                        // The hitbox collider may be underneath the base collider. Fire a raycast to detemine if there are any colliders underneath the hit collider
                        // that should apply a multiplier.
                        var hitCount = Physics.RaycastNonAlloc(position, direction, m_RaycastHits, distance,
                                                               ~(1 << LayerManager.IgnoreRaycast | 1 << LayerManager.Overlay | 1 << LayerManager.VisualEffect), QueryTriggerInteraction.Ignore);
                        for (int i = 0; i < hitCount; ++i)
                        {
                            var closestRaycastHit = QuickSelect.SmallestK(m_RaycastHits, hitCount, i, m_RaycastHitComparer);
                            if (closestRaycastHit.collider == hitCollider)
                            {
                                continue;
                            }
                            // A new collider has been found - stop iterating if the hitbox map exists and use the hitbox multiplier.
                            if (m_ColliderHitboxMap.TryGetValue(closestRaycastHit.collider, out hitbox))
                            {
                                amount     *= hitbox.DamageMultiplier;
                                hitCollider = hitbox.Collider;
                                break;
                            }
                        }
                    }
                }
            }

            // Apply the damage to the shield first because the shield can regenrate.
            if (m_ShieldAttribute != null && m_ShieldAttribute.Value > m_ShieldAttribute.MinValue)
            {
                var shieldAmount = Mathf.Min(amount, m_ShieldAttribute.Value - m_ShieldAttribute.MinValue);
                amount -= shieldAmount;
                m_ShieldAttribute.Value -= shieldAmount;
            }

            // Decrement the health by remaining amount after the shield has taken damage.
            if (m_HealthAttribute != null && m_HealthAttribute.Value > m_HealthAttribute.MinValue)
            {
                m_HealthAttribute.Value -= Mathf.Min(amount, m_HealthAttribute.Value - m_HealthAttribute.MinValue);
            }

            var force = direction * forceMagnitude;
            if (forceMagnitude > 0)
            {
                // Apply a force to the object.
                if (m_ForceObject != null)
                {
                    m_ForceObject.AddForce(force, frames);
                }
                else
                {
                    // Apply a force to the rigidbody if the object isn't a character.
                    if (m_Rigidbody != null && !m_Rigidbody.isKinematic)
                    {
                        if (radius == 0)
                        {
                            m_Rigidbody.AddForceAtPosition(force * MathUtility.RigidbodyForceMultiplier, position);
                        }
                        else
                        {
                            m_Rigidbody.AddExplosionForce(force.magnitude * MathUtility.RigidbodyForceMultiplier, position, radius);
                        }
                    }
                }
            }

            // Let other interested objects know that the object took damage.
            EventHandler.ExecuteEvent <float, Vector3, Vector3, GameObject, Collider>(m_GameObject, "OnHealthDamage", amount, position, force, attacker, hitCollider);
            if (m_OnDamageEvent != null)
            {
                m_OnDamageEvent.Invoke(amount, position, force, attacker);
            }

            // The object is dead when there is no more health or shield.
            if (!IsAlive())
            {
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
                if (m_NetworkInfo == null || m_NetworkInfo.IsLocalPlayer())
                {
#endif
                Die(position, force, attacker);
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            }
#endif
            }
            else
            {
                // Play any take damage audio if the object did not die. If the object died then the death audio will play.
                m_TakeDamageAudioClipSet.PlayAudioClip(m_GameObject);
            }
        }
Beispiel #12
0
        /// <summary>
        /// The object is no longer alive.
        /// </summary>
        /// <param name="position">The position of the damage.</param>
        /// <param name="force">The amount of force applied to the object while taking the damage.</param>
        /// <param name="attacker">The GameObject that killed the character.</param>
        public virtual void Die(Vector3 position, Vector3 force, GameObject attacker)
        {
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_NetworkInfo != null && m_NetworkInfo.IsServer())
            {
                m_NetworkHealthMonitor.Die(position, force, attacker);
            }
#endif

            // Spawn any objects on death, such as an explosion if the object is an explosive barrel.
            if (m_SpawnedObjectsOnDeath != null)
            {
                for (int i = 0; i < m_SpawnedObjectsOnDeath.Length; ++i)
                {
                    var       spawnedObject = ObjectPool.Instantiate(m_SpawnedObjectsOnDeath[i], transform.position, transform.rotation);
                    Explosion explosion;
                    if ((explosion = spawnedObject.GetCachedComponent <Explosion>()) != null)
                    {
                        explosion.Explode(gameObject);
                    }
                    var rigidbodies = spawnedObject.GetComponentsInChildren <Rigidbody>();
                    for (int j = 0; j < rigidbodies.Length; ++j)
                    {
                        rigidbodies[j].AddForceAtPosition(force, position);
                    }
                }
            }

            // Destroy any objects on death. The objects will be placed back in the object pool if they were created within it otherwise the object will be destroyed.
            if (m_DestroyedObjectsOnDeath != null)
            {
                for (int i = 0; i < m_DestroyedObjectsOnDeath.Length; ++i)
                {
                    if (ObjectPool.InstantiatedWithPool(m_DestroyedObjectsOnDeath[i]))
                    {
                        ObjectPool.Destroy(m_DestroyedObjectsOnDeath[i]);
                    }
                    else
                    {
                        Object.Destroy(m_DestroyedObjectsOnDeath[i]);
                    }
                }
            }

            // Change the layer to a death layer.
            if (m_DeathLayer.value != 0)
            {
                m_AliveLayer       = m_GameObject.layer;
                m_GameObject.layer = m_DeathLayer;
            }

            // Play any take death audio.
            m_DeathAudioClipSet.PlayAudioClip(m_GameObject);

            // Deactivate the object if requested.
            if (m_DeactivateOnDeath)
            {
                Scheduler.Schedule(m_DeactivateOnDeathDelay, Deactivate);
            }

            // The attributes shouldn't regenerate.
            if (m_ShieldAttribute != null)
            {
                m_ShieldAttribute.CancelAutoUpdate();
            }
            if (m_HealthAttribute != null)
            {
                m_HealthAttribute.CancelAutoUpdate();
            }

            // Notify those interested.
            EventHandler.ExecuteEvent <Vector3, Vector3, GameObject>(m_GameObject, "OnDeath", position, force, attacker);
            if (m_OnDeathEvent != null)
            {
                m_OnDeathEvent.Invoke(position, force, attacker);
            }
        }
 /// <summary>
 /// Plays the audio clip with a random set index.
 /// </summary>
 /// <param name="gameObject">The GameObject that is playing the audio clip.</param>
 /// <param name="reservedIndex">The index of the component that should be played. -1 indicates any component.</param>
 public void PlayAudioClip(GameObject gameObject, int reservedIndex)
 {
     m_AudioClipSet.PlayAudioClip(gameObject, reservedIndex);
 }
Beispiel #14
0
        /// <summary>
        /// Initializes the object with the specified velocity and torque.
        /// </summary>
        /// <param name="velocity">The starting velocity.</param>
        /// <param name="torque">The starting torque.</param>
        /// <param name="originator">The object that instantiated the trajectory object.</param>
        /// <param name="originatorCollisionCheck">Should a collision check against the originator be performed?</param>
        /// <param name="defaultNormalizedGravity">The normalized gravity direction if a character isn't specified for the originator.</param>
        public virtual void Initialize(Vector3 velocity, Vector3 torque, GameObject originator, bool originatorCollisionCheck, Vector3 defaultNormalizedGravity)
        {
            InitializeComponentReferences();

            m_Velocity = velocity / m_Mass * m_StartVelocityMultiplier;
            m_Torque   = torque;
            if (originator != null && originator != m_Originator)
            {
                m_Originator                    = originator;
                m_OriginatorTransform           = m_Originator.transform;
                m_OriginatorCharacterLocomotion = m_Originator.GetCachedComponent <UltimateCharacterLocomotion>();
                if (m_OriginatorCharacterLocomotion != null)
                {
                    m_NormalizedGravity = m_OriginatorCharacterLocomotion.GravityDirection;
                    m_TimeScale         = m_OriginatorCharacterLocomotion.TimeScale;
                    EventHandler.RegisterEvent <float>(m_Originator, "OnCharacterChangeTimeScale", OnChangeTimeScale);
                }
                else
                {
                    m_NormalizedGravity = defaultNormalizedGravity;
                    m_TimeScale         = 1;
                }
            }
            else
            {
                m_NormalizedGravity   = defaultNormalizedGravity;
                m_TimeScale           = 1;
                m_OriginatorTransform = null;
            }
            m_Gravity = m_NormalizedGravity * m_GravityMagnitude;
            m_OriginatorCollisionCheck = originatorCollisionCheck && m_Originator != null;

            m_Platform        = null;
            m_MovementSettled = m_RotationSettled = false;
            m_InCollision     = false;
            m_Bounced         = false;
            if (m_Collider != null)
            {
                m_Collider.enabled = true;
            }
            m_ActiveAudioClipSet.PlayAudioClip(m_GameObject, 0, true);
            enabled = true;

            // Set the layer to prevent the current object from getting in the way of the casts.
            var previousLayer = m_GameObject.layer;

            m_GameObject.layer = LayerManager.IgnoreRaycast;

            // The object could start in a collision state.
            if (m_OriginatorCollisionCheck && OverlapCast(m_Transform.position, m_Transform.rotation))
            {
                OnCollision(null);
                if (m_BounceMode == BounceMode.None)
                {
                    m_MovementSettled = m_RotationSettled = true;
                }
                else
                {
                    // Update the velocity to the reflection direction. Use the originator's forward direction as the normal because the actual collision point is not determined.
                    m_Velocity = Vector3.Reflect(m_Velocity, -m_OriginatorTransform.forward) * m_BounceMultiplier;
                }
            }

            m_GameObject.layer = previousLayer;
        }
Beispiel #15
0
 /// <summary>
 /// Plays the audio clip with a random set index.
 /// </summary>
 /// <param name="gameObject">The GameObject that is playing the audio clip.</param>
 public void PlayAudioClip(GameObject gameObject)
 {
     m_AudioClipSet.PlayAudioClip(gameObject);
 }