示例#1
0
        /// <summary>
        /// The character has either landed or just left the ground.
        /// </summary>
        /// <param name="grounded">Is the character on the ground?</param>
        private void OnGrounded(bool grounded)
        {
            if (grounded)
            {
                if (IsActive)
                {
                    StopAbility(true);
                }
                m_AirborneJumpCount = 0;
                m_JumpApplied       = false;
                // Remember the land time to prevent jumping more than the JumpReoccuranceDelay.
                // Add the deltaTime to prevent the ability from starting during the same frame. This can happen if the character is updated within FixedUpdate
                // but the input is updated within Update.
                m_LandTime  = Time.time + Time.deltaTime;
                m_InAirTime = -1;

                // Unregister the jump input within OnGrounded so a repeated jump can be applied when fall is active.
                if (m_AirborneJumpInput != null)
                {
                    m_Handler.UnregisterInputEvent(m_AirborneJumpInput);
                    GenericObjectPool.Return(m_AirborneJumpInput);
                    m_AirborneJumpInput = null;
                }
                EventHandler.UnregisterEvent(m_GameObject, "OnJumpAbilityAirborneJump", OnPerformAirborneJump);
                m_AirborneJumpRegistered = false;
            }
            else if (!IsActive)
            {
                m_InAirTime = Time.time;
            }
        }
示例#2
0
        /// <summary>
        /// The GameObject has been destroyed.
        /// </summary>
        public override void OnDestroy()
        {
            base.OnDestroy();

            if (m_Handler != null)
            {
                if (m_Rotate)
                {
                    m_Handler.UnregisterInputEvent(m_StopRotateInputEvent);
                }
                else
                {
                    m_Handler.UnregisterInputEvent(m_StartRotateInputEvent);
                }

                m_Handler.UnregisterInputEvent(m_TurnInputEvent);
                m_Handler.UnregisterInputEvent(m_AutoMoveInputEvent);

                GenericObjectPool.Return(m_StartRotateInputEvent);
                GenericObjectPool.Return(m_StopRotateInputEvent);
                GenericObjectPool.Return(m_TurnInputEvent);
                GenericObjectPool.Return(m_AutoMoveInputEvent);
            }
            EventHandler.UnregisterEvent(m_GameObject, "OnRPGMovementTypeStartRotate", OnStartRotate);
            EventHandler.UnregisterEvent(m_GameObject, "OnRPGMovementTypeStopRotate", OnStopRotate);
            EventHandler.UnregisterEvent <float>(m_GameObject, "OnRPGMovementTypeTurn", OnTurn);
            EventHandler.UnregisterEvent(m_GameObject, "OnRPGMovementTypeAutoMove", OnToggleAutoMove);
        }
示例#3
0
        /// <summary>
        /// Perform the impact action.
        /// </summary>
        /// <param name="castID">The ID of the cast.</param>
        /// <param name="source">The object that caused the cast.</param>
        /// <param name="target">The object that was hit by the cast.</param>
        /// <param name="hit">The raycast that caused the impact.</param>
        protected override void ImpactInternal(uint castID, GameObject source, GameObject target, RaycastHit hit)
        {
            var targetAttributeManager = target.GetCachedParentComponent <AttributeManager>();

            if (targetAttributeManager == null)
            {
                return;
            }

            // The impact action can collide with multiple objects. Use a pooled version of the AttributeModifier for each collision.
            var attributeModifier = GenericObjectPool.Get <AttributeModifier>();

            if (!attributeModifier.Initialize(m_AttributeModifier, targetAttributeManager))
            {
                GenericObjectPool.Return(attributeModifier);
                return;
            }

            // The attribute exists. Enable the modifier. Return the modifier as soon as it is complete (which may be immediate).
            attributeModifier.EnableModifier(true);
            if (attributeModifier.AutoUpdating && attributeModifier.AutoUpdateDuration > 0)
            {
                EventHandler.RegisterEvent <AttributeModifier, bool>(attributeModifier, "OnAttributeModifierAutoUpdateEnable", ModifierAutoUpdateEnabled);
            }
            else
            {
                GenericObjectPool.Return(attributeModifier);
            }
        }
 public override void ReturnToPool()
 {
     Clear();
     Width  = 0;
     Height = 0;
     Pool.Return(this);
 }
示例#5
0
        /// <summary>
        /// The character has either landed or just left the ground.
        /// </summary>
        /// <param name="grounded">Is the character on the ground?</param>
        private void OnGrounded(bool grounded)
        {
            if (grounded)
            {
                if (IsActive)
                {
                    StopAbility(true);
                }
                m_AirborneJumpCount = 0;
                m_JumpApplied       = false;
                // Remember the land time to prevent jumping more than the JumpReoccuranceDelay.
                m_LandTime  = Time.time;
                m_InAirTime = -1;

                // Unregister the jump input within OnGrounded so a repeated jump can be applied when fall is active.
                if (m_AirborneJumpInput != null)
                {
                    m_Handler.UnregisterInputEvent(m_AirborneJumpInput);
                    GenericObjectPool.Return(m_AirborneJumpInput);
                    m_AirborneJumpInput = null;
                }
                EventHandler.UnregisterEvent(m_GameObject, "OnJumpAbilityAirborneJump", OnAirborneJump);
                m_AirborneJumpRegistered = false;
            }
            else if (!IsActive)
            {
                m_InAirTime = Time.time;
            }
        }
示例#6
0
        /// <summary>
        /// The object has 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 void Damage(float amount, Vector3 position, Vector3 direction, float forceMagnitude, int frames, float radius, GameObject attacker, object attackerObject, Collider hitCollider)
        {
            var pooledDamageData = GenericObjectPool.Get <DamageData>();

            pooledDamageData.SetDamage(amount, position, direction, forceMagnitude, frames, radius, attacker, attackerObject, hitCollider);
            Damage(pooledDamageData);
            GenericObjectPool.Return(pooledDamageData);
        }
示例#7
0
        /// <summary>
        /// The AttributeModifier auto updater has been enabled or disabled.
        /// </summary>
        /// <param name="attributeModifier">The modifier that has been enabled or disabled.</param>
        /// <param name="enable">True if the modifier has been enabled.</param>
        private void ModifierAutoUpdateEnabled(AttributeModifier attributeModifier, bool enable)
        {
            if (enable)
            {
                return;
            }

            EventHandler.UnregisterEvent <AttributeModifier, bool>(attributeModifier, "OnAttributeModifierAutoUpdateEnable", ModifierAutoUpdateEnabled);
            GenericObjectPool.Return(attributeModifier);
        }
        /// <summary>
        /// One or more hit indicators are shown.
        /// </summary>
        private void Update()
        {
            for (int i = m_ActiveDamageIndicatorCount - 1; i > -1; --i)
            {
                // The alpha value is determined by the amount of time the damage indicator has been visible. The indicator should be visible for a time of m_IndicatorVisiblityTime
                // with no fading. After m_IndicatorVisiblityTime the indicator should fade for visibilityTime.
                var alpha = (m_IndicatorFadeTime - (Time.time - (m_ActiveDamageIndicators[i].DisplayTime + m_IndicatorVisiblityTime))) / m_IndicatorFadeTime;
                if (alpha <= 0)
                {
                    m_ActiveDamageIndicators[i].GameObject.SetActive(false);
                    GenericObjectPool.Return(m_ActiveDamageIndicators[i]);
                    m_ActiveDamageIndicatorCount--;
                    // Sort the array so the complete indicators are at the end.
                    for (int j = i; j < m_ActiveDamageIndicatorCount; ++j)
                    {
                        m_ActiveDamageIndicators[j] = m_ActiveDamageIndicators[j + 1];
                    }
                    continue;
                }
                var color = m_ActiveDamageIndicators[i].Image.color;
                color.a = alpha;
                m_ActiveDamageIndicators[i].Image.color = color;

                var attackerPosition = (m_FollowAttacker && m_CharacterTransform != m_ActiveDamageIndicators[i].Attacker) ?
                                       m_ActiveDamageIndicators[i].Attacker.position : m_ActiveDamageIndicators[i].Position;

                // Adjust the hit position.
                var localHitPosition = m_ActiveDamageIndicators[i].Attacker.InverseTransformPoint(m_ActiveDamageIndicators[i].Position);
                localHitPosition.x = localHitPosition.z = 0;
                attackerPosition  += m_ActiveDamageIndicators[i].Attacker.TransformDirection(localHitPosition);

                var screenPoint       = m_Camera.WorldToScreenPoint(attackerPosition);
                var centerScreenPoint = ((new Vector2(screenPoint.x, screenPoint.y) - (new Vector2(m_Camera.pixelWidth, m_Camera.pixelHeight) / 2)) * Mathf.Sign(screenPoint.z)).normalized;

                var angle = Vector2.SignedAngle(centerScreenPoint, Vector2.right);
                m_ActiveDamageIndicators[i].Angle = 90 - angle;

                // Face the image in the direction of the angle.
                var rotation = m_ActiveDamageIndicators[i].RectTransform.localEulerAngles;
                rotation.z = m_ActiveDamageIndicators[i].Angle;
                m_ActiveDamageIndicators[i].RectTransform.localEulerAngles = rotation;

                // Position the indicator relative to the direction.
                var position = m_ActiveDamageIndicators[i].RectTransform.localPosition;
                position.x = Mathf.Sin(m_ActiveDamageIndicators[i].Angle * Mathf.Deg2Rad) * m_IndicatorOffset;
                position.y = -Mathf.Cos(m_ActiveDamageIndicators[i].Angle * Mathf.Deg2Rad) * m_IndicatorOffset;
                m_ActiveDamageIndicators[i].RectTransform.localPosition = position;
            }

            // The component can be disabled when the damage indicators have disappeared.
            if (m_ActiveDamageIndicatorCount == 0)
            {
                m_GameObject.SetActive(false);
            }
        }
 /// <summary>
 /// The character has respawned.
 /// </summary>
 private void OnRespawn()
 {
     // No indicators should be shown when the character respawns.
     for (int i = m_ActiveDamageIndicatorCount - 1; i > -1; --i)
     {
         m_ActiveDamageIndicators[i].GameObject.SetActive(false);
         GenericObjectPool.Return(m_ActiveDamageIndicators[i]);
     }
     m_ActiveDamageIndicatorCount = 0;
     m_GameObject.SetActive(false);
 }
示例#10
0
        /// <summary>
        /// The action has started.
        /// </summary>
        /// <param name="origin">The location that the cast originates from.</param>
        public override void Start(Transform origin)
        {
            // Initialize any starting values after all of the actions have been deserialized.
            if (m_ColorID == 0)
            {
                m_ColorID = Shader.PropertyToID(m_ColorPropertyName);
                if (!m_BeginAction && m_MagicItem.BeginActions != null)
                {
                    for (int i = 0; i < m_MagicItem.BeginActions.Length; ++i)
                    {
                        if (m_MagicItem.BeginActions[i] is FadeMaterials)
                        {
                            m_BeginFadeMaterials = m_MagicItem.BeginActions[i] as FadeMaterials;
                            break;
                        }
                    }
                }
            }

            // The Object Fader should reset.
            EventHandler.ExecuteEvent(m_Character, "OnCharacterIndependentFade", true, true);
            if (m_BeginFadeMaterials == null)
            {
                // Return the previous objects.
                if (m_OriginalMaterialValuesMap.Count > 0)
                {
                    for (int i = 0; i < m_Materials.Count; ++i)
                    {
                        GenericObjectPool.Return(m_OriginalMaterialValuesMap[m_Materials[i]]);
                        m_OriginalMaterialValuesMap.Remove(m_Materials[i]);
                    }
                }
                m_Materials.Clear();
                m_ActiveMaterials.Clear();

                EnableRendererFade();
            }
            else
            {
                m_Materials                 = m_BeginFadeMaterials.Materials;
                m_ActiveMaterials           = m_BeginFadeMaterials.ActiveMaterials;
                m_OriginalMaterialValuesMap = m_BeginFadeMaterials.OriginalMaterialValuesMap;
            }
            m_Active = true;

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            // Update isn't called automatically for the remote players.
            if (m_MagicItem.NetworkInfo != null && !m_MagicItem.NetworkInfo.IsLocalPlayer())
            {
                m_UpdateEvent = SchedulerBase.Schedule(0.001f, Update);
            }
#endif
        }
        /// <summary>
        /// One or more hit indicators are shown.
        /// </summary>
        private void Update()
        {
            for (int i = m_ActiveDamageIndicatorCount - 1; i > -1; --i)
            {
                // The alpha value is determined by the amount of time the damage indicator has been visible. The indicator should be visible for a time of m_IndicatorVisiblityTime
                // with no fading. After m_IndicatorVisiblityTime the indicator should fade for visibilityTime.
                var alpha = (m_IndicatorFadeTime - (Time.time - (m_ActiveDamageIndicators[i].DisplayTime + m_IndicatorVisiblityTime))) / m_IndicatorFadeTime;
                if (alpha <= 0)
                {
                    m_ActiveDamageIndicators[i].GameObject.SetActive(false);
                    GenericObjectPool.Return(m_ActiveDamageIndicators[i]);
                    m_ActiveDamageIndicatorCount--;
                    // Sort the array so the complete indicators are at the end.
                    for (int j = i; j < m_ActiveDamageIndicatorCount; ++j)
                    {
                        m_ActiveDamageIndicators[j] = m_ActiveDamageIndicators[j + 1];
                    }
                    continue;
                }
                var color = m_ActiveDamageIndicators[i].Image.color;
                color.a = alpha;
                m_ActiveDamageIndicators[i].Image.color = color;

                var direction = Vector3.ProjectOnPlane(m_CharacterTransform.position - ((m_FollowAttacker && m_CharacterTransform != m_ActiveDamageIndicators[i].Attacker) ?
                                                                                        m_ActiveDamageIndicators[i].Attacker.position : m_ActiveDamageIndicators[i].Position),
                                                       m_CharacterLocomotion.Up);
                // The hit indicator is shown on a 2D canvas so the y direction should be ignored.
                direction.y = 0;
                direction.Normalize();

                var angle = Vector3.Angle(direction, m_CameraTransform.forward) * Mathf.Sign(Vector3.Dot(direction, m_CameraTransform.right));
                m_ActiveDamageIndicators[i].Angle = angle;

                // Face the image in the direction of the angle.
                var rotation = m_ActiveDamageIndicators[i].RectTransform.localEulerAngles;
                rotation.z = -m_ActiveDamageIndicators[i].Angle;
                m_ActiveDamageIndicators[i].RectTransform.localEulerAngles = rotation;

                // Position the indicator relative to the direction.
                var position = m_ActiveDamageIndicators[i].RectTransform.localPosition;
                position.x = -Mathf.Sin(m_ActiveDamageIndicators[i].Angle * Mathf.Deg2Rad) * m_IndicatorOffset;
                position.y = -Mathf.Cos(m_ActiveDamageIndicators[i].Angle * Mathf.Deg2Rad) * m_IndicatorOffset;
                m_ActiveDamageIndicators[i].RectTransform.localPosition = position;
            }

            // The component can be disabled when the damage indicators have disappeared.
            if (m_ActiveDamageIndicatorCount == 0)
            {
                m_GameObject.SetActive(false);
            }
        }
示例#12
0
        /// <summary>
        /// The ability has stopped running.
        /// </summary>
        /// <param name="force">Was the ability force stopped?</param>
        protected override void AbilityStopped(bool force)
        {
            base.AbilityStopped(force);

            m_JumpApplied = m_Jumping = false;

            // Unregister for the ability input events.
            if (m_HoldInput != null)
            {
                m_Handler.UnregisterInputEvent(m_HoldInput);
                GenericObjectPool.Return(m_HoldInput);
            }
            EventHandler.UnregisterEvent(m_GameObject, "OnJumpAbilityReleaseHold", OnReleaseHold);
        }
示例#13
0
        /// <summary>
        /// Removes the obstructing material at the specified index from the ObstructingMaterials array.
        /// </summary>
        /// <param name="index">The index of the obstructing material to remove.</param>
        private void RemoveObstructingMaterial(int index)
        {
            var originalMaterialValue = m_OriginalMaterialValuesMap[m_ObstructingMaterials[index]];

            RevertMaterial(m_ObstructingMaterials[index], originalMaterialValue);
            GenericObjectPool.Return(originalMaterialValue);
            m_OriginalMaterialValuesMap.Remove(m_ObstructingMaterials[index]);

            // The object is no longer faded. Move the array elements down one.
            for (int j = index; j < m_ObstructingMaterialsCount - 1; ++j)
            {
                m_ObstructingMaterials[j] = m_ObstructingMaterials[j + 1];
            }
            m_ObstructingMaterialsCount--;
        }
示例#14
0
        /// <summary>
        /// Internal method which stops managing the kinematic object at the specified index.
        /// </summary>
        /// <param name="kinematicObjectIndex">The index of the kinematic object within the characters array.</param>
        private void UnregisterKinematicObjectInternal(int kinematicObjectIndex)
        {
            if (kinematicObjectIndex < 0)
            {
                return;
            }

            GenericObjectPool.Return(m_KinematicObjects[kinematicObjectIndex]);
            // Keep the array packed by shifting all of the subsequent elements over by one.
            for (int i = kinematicObjectIndex + 1; i < m_KinematicObjectCount; ++i)
            {
                m_KinematicObjects[i - 1] = m_KinematicObjects[i];
                m_KinematicObjects[i - 1].IKinematicObject.KinematicObjectIndex = i - 1;
            }
            m_KinematicObjectCount--;
        }
示例#15
0
        /// <summary>
        /// Internal method which stops managing the camera at the specified index.
        /// </summary>
        /// <param name="characterIndex">The index of the camera within the cameras array.</param>
        private void UnregisterCameraInternal(int cameraIndex)
        {
            if (cameraIndex < 0)
            {
                return;
            }

            m_Cameras[cameraIndex].UnregisterCamera();
            GenericObjectPool.Return(m_Cameras[cameraIndex]);
            // Keep the array packed by shifting all of the subsequent elements over by one.
            for (int i = cameraIndex + 1; i < m_CameraCount; ++i)
            {
                m_Cameras[i - 1] = m_Cameras[i];
                m_Cameras[i - 1].CameraController.KinematicObjectIndex = i - 1;
            }
            m_CameraCount--;
        }
示例#16
0
        /// <summary>
        /// Internal method which stops managing the character at the specified index.
        /// </summary>
        /// <param name="characterIndex">The index of the character within the characters array.</param>
        private void UnregisterCharacterInternal(int characterIndex)
        {
            if (characterIndex < 0)
            {
                return;
            }

            m_Characters[characterIndex].UnregisterCharacter();
            GenericObjectPool.Return(m_Characters[characterIndex]);
            // Keep the array packed by shifting all of the subsequent elements over by one.
            for (int i = characterIndex + 1; i < m_CharacterCount; ++i)
            {
                m_Characters[i - 1] = m_Characters[i];
                m_Characters[i - 1].CharacterLocomotion.KinematicObjectIndex = i - 1;
            }
            m_CharacterCount--;
        }
示例#17
0
        /// <summary>
        /// The view type has changed.
        /// </summary>
        /// <param name="activate">Should the current view type be activated?</param>
        /// <param name="pitch">The pitch of the camera (in degrees).</param>
        /// <param name="yaw">The yaw of the camera (in degrees).</param>
        /// <param name="characterRotation">The rotation of the character.</param>
        public override void ChangeViewType(bool activate, float pitch, float yaw, Quaternion characterRotation)
        {
            base.ChangeViewType(activate, pitch, yaw, characterRotation);

            if (activate)
            {
                // Work with the handler to listen for any input events.
                if (m_Handler != null)
                {
                    m_StartFreeMovementInputEvent = GenericObjectPool.Get <ActiveInputEvent>();
                    m_StartFreeMovementInputEvent.Initialize(ActiveInputEvent.Type.ButtonDown, m_CameraFreeMovementInputName, "OnRPGViewTypeStartFreeMovement");

                    m_StopFreeMovementInputEvent = GenericObjectPool.Get <ActiveInputEvent>();
                    m_StopFreeMovementInputEvent.Initialize(ActiveInputEvent.Type.ButtonUp, m_CameraFreeMovementInputName, "OnRPGViewTypeStopFreeMovement");

                    m_Handler.RegisterInputEvent(m_StartFreeMovementInputEvent);
                }
                EventHandler.RegisterEvent(m_GameObject, "OnRPGViewTypeStartFreeMovement", OnStartFreeMovement);
                EventHandler.RegisterEvent(m_GameObject, "OnRPGViewTypeStopFreeMovement", OnStopFreeMovement);
                EventHandler.RegisterEvent(m_Character, "OnRPGMovementTypeStartRotate", OnStartCharacterRotate);
                EventHandler.RegisterEvent(m_Character, "OnRPGMovementTypeStopRotate", OnStopCharacterRotate);
            }
            else
            {
                // The ViewType no longer needs to listen for input events when to ViewType is no longer active.
                if (m_Handler != null)
                {
                    if (m_FreeMovement)
                    {
                        m_Handler.UnregisterAbilityInputEvent(m_StopFreeMovementInputEvent);
                    }
                    else
                    {
                        m_Handler.UnregisterAbilityInputEvent(m_StartFreeMovementInputEvent);
                    }

                    GenericObjectPool.Return(m_StartFreeMovementInputEvent);
                    GenericObjectPool.Return(m_StopFreeMovementInputEvent);
                }
                EventHandler.UnregisterEvent(m_GameObject, "OnRPGViewTypeStartFreeMovement", OnStartFreeMovement);
                EventHandler.UnregisterEvent(m_GameObject, "OnRPGViewTypeStopFreeMovement", OnStopFreeMovement);
                EventHandler.UnregisterEvent(m_Character, "OnRPGMovementTypeStartRotate", OnStartCharacterRotate);
                EventHandler.UnregisterEvent(m_Character, "OnRPGMovementTypeStopRotate", OnStopCharacterRotate);
            }
        }
示例#18
0
            /// <summary>
            /// Stops managing the character.
            /// </summary>
            public void UnregisterCharacter()
            {
                if (m_CompleteInitEvent != null)
                {
                    Scheduler.Cancel(m_CompleteInitEvent);
                    m_CompleteInitEvent = null;
                }

                if (m_SmoothedBones != null)
                {
                    for (int i = 0; i < m_SmoothedBones.Length; ++i)
                    {
                        GenericObjectPool.Return(m_SmoothedBones[i]);
                    }
                    m_SmoothedBones = null;
                }
                EventHandler.UnregisterEvent <ILookSource>(m_CharacterLocomotion.gameObject, "OnCharacterAttachLookSource", OnAttachLookSource);
            }
示例#19
0
        /// <summary>
        /// The ability has stopped running.
        /// </summary>
        /// <param name="force">Was the ability force stopped?</param>
        protected override void AbilityStopped(bool force)
        {
            base.AbilityStopped(force);

            // Update one last time with an axis value of 0 to return to the starting position.
            m_AxisValue = 0;
            UpdateLean(true);

            // The collider is no longer needed.
            if (m_ColliderGameObject != null)
            {
                m_ColliderGameObject.SetActive(false);
            }

            if (m_Handler != null)
            {
                m_Handler.UnregisterInputEvent(m_LeanInput);
                GenericObjectPool.Return(m_LeanInput);
            }
            EventHandler.UnregisterEvent <float>(m_GameObject, "OnLeanInputUpdate", OnInputUpdate);
        }
示例#20
0
 /// <summary>
 /// The view type has changed.
 /// </summary>
 /// <param name="activate">Should the current view type be activated?</param>
 /// <param name="pitch">The pitch of the camera (in degrees).</param>
 /// <param name="yaw">The yaw of the camera (in degrees).</param>
 /// <param name="characterRotation">The rotation of the character.</param>
 public override void ChangeViewType(bool activate, float pitch, float yaw, Quaternion characterRotation)
 {
     if (activate)
     {
         m_Pitch             = pitch;
         m_Yaw               = yaw;
         m_CharacterRotation = characterRotation;
         if (m_CharacterLocomotion.Platform != null)
         {
             UpdatePlatformRotationOffset(m_CharacterLocomotion.Platform);
         }
         if (m_Camera.fieldOfView != m_FieldOfView)
         {
             m_FieldOfViewChangeTime = Time.time + m_FieldOfViewDamping / m_CharacterLocomotion.TimeScale;
         }
         if (m_StepZoomSensitivity > 0)
         {
             if (m_Handler != null)
             {
                 m_StepZoomInputEvent = GenericObjectPool.Get <ActiveInputEvent>();
                 m_StepZoomInputEvent.Initialize(ActiveInputEvent.Type.Axis, m_StepZoomInputName, "OnThirdPersonViewTypeStepZoom");
                 m_Handler.RegisterInputEvent(m_StepZoomInputEvent);
             }
             EventHandler.RegisterEvent <float>(m_GameObject, "OnThirdPersonViewTypeStepZoom", OnStepZoom);
         }
     }
     else
     {
         if (m_StepZoomSensitivity > 0)
         {
             if (m_Handler != null)
             {
                 m_StepZoomInputEvent = GenericObjectPool.Get <ActiveInputEvent>();
                 m_Handler.UnregisterAbilityInputEvent(m_StepZoomInputEvent);
                 GenericObjectPool.Return(m_StepZoomInputEvent);
             }
             EventHandler.UnregisterEvent <float>(m_GameObject, "OnThirdPersonViewTypeStepZoom", OnStepZoom);
         }
     }
 }
示例#21
0
        /// <summary>
        /// Perform the impact action.
        /// </summary>
        /// <param name="castID">The ID of the cast.</param>
        /// <param name="source">The object that caused the cast.</param>
        /// <param name="target">The object that was hit by the cast.</param>
        /// <param name="hit">The raycast that caused the impact.</param>
        protected override void ImpactInternal(uint castID, GameObject source, GameObject target, RaycastHit hit)
        {
            var damageTarget = DamageUtility.GetDamageTarget(target);

            if (damageTarget == null || !damageTarget.IsAlive())
            {
                if (m_InterruptImpactOnNullHealth)
                {
                    m_MagicItem.InterruptImpact();
                }
                return;
            }
            var pooledDamageData = GenericObjectPool.Get <DamageData>();

            pooledDamageData.SetDamage(m_Amount, source.transform.position, (source.transform.position - target.transform.position), m_ForceMagnitude, m_ForceFrames, 0, source, this, null);
            if (m_DamageProcessor == null)
            {
                m_DamageProcessor = DamageProcessor.Default;
            }
            m_DamageProcessor.Process(damageTarget, pooledDamageData);
            GenericObjectPool.Return(pooledDamageData);
        }
示例#22
0
        /// <summary>
        /// The object has collided with another object.
        /// </summary>
        /// <param name="hit">The RaycastHit of the object. Can be null.</param>
        protected override void OnCollision(RaycastHit?hit)
        {
            base.OnCollision(hit);

            var forceDestruct = false;

            if (m_CollisionMode == CollisionMode.Collide)
            {
                // When there is a collision the object should move to the position that was hit so if it's not destroyed then it looks like it
                // is penetrating the hit object.
                if (hit != null && hit.HasValue && m_Collider != null)
                {
                    var closestPoint = m_Collider.ClosestPoint(hit.Value.point);
                    m_Transform.position += (hit.Value.point - closestPoint);
                    // Only set the parent to the hit transform on uniform objects to prevent stretching.
                    if (MathUtility.IsUniform(hit.Value.transform.localScale))
                    {
                        // The parent layer must be within the sticky layer mask.
                        if (MathUtility.InLayerMask(hit.Value.transform.gameObject.layer, m_StickyLayers))
                        {
                            m_Transform.parent = hit.Value.transform;

                            // If the destructible sticks to a character then the object should be added as a sub collider so collisions will be ignored.
                            m_StickyCharacterLocomotion = hit.Value.transform.gameObject.GetCachedComponent <UltimateCharacterLocomotion>();
                            if (m_StickyCharacterLocomotion != null)
                            {
                                m_StickyCharacterLocomotion.AddIgnoredCollider(m_Collider);
                            }
                        }
                        else
                        {
                            forceDestruct = true;
                        }
                    }
                }
                if (m_TrailRenderer != null)
                {
                    m_TrailRenderer.enabled = false;
                }
            }

            var destructionDelay = m_DestructionDelay;

            if (m_ParticleSystem != null && m_WaitForParticleStop)
            {
                destructionDelay = m_ParticleSystem.main.duration;
                m_ParticleSystem.Stop(true, ParticleSystemStopBehavior.StopEmitting);
                Stop();
            }

            // The object may not have been initialized before it collides.
            if (m_GameObject == null)
            {
                InitializeComponentReferences();
            }

            if (hit != null && hit.HasValue)
            {
                var hitValue      = hit.Value;
                var hitGameObject = hitValue.collider.gameObject;
                // The shield can absorb some (or none) of the damage from the destructible.
                var damageAmount = m_DamageAmount;
#if ULTIMATE_CHARACTER_CONTROLLER_MELEE
                ShieldCollider shieldCollider;
                if ((shieldCollider = hitGameObject.GetCachedComponent <ShieldCollider>()) != null)
                {
                    damageAmount = shieldCollider.Shield.Damage(this, damageAmount);
                }
#endif

                // Allow a custom event to be received.
                EventHandler.ExecuteEvent <float, Vector3, Vector3, GameObject, object, Collider>(hitGameObject, "OnObjectImpact", damageAmount, hitValue.point, m_Velocity.normalized * m_ImpactForce, m_Originator, this, hitValue.collider);
                if (m_OnImpactEvent != null)
                {
                    m_OnImpactEvent.Invoke(damageAmount, hitValue.point, m_Velocity.normalized * m_ImpactForce, m_Originator);
                }

                // If the shield didn't absorb all of the damage then it should be applied to the character.
                if (damageAmount > 0)
                {
                    var damageTarget = DamageUtility.GetDamageTarget(hitGameObject);
                    if (damageTarget != null)
                    {
                        var pooledDamageData = GenericObjectPool.Get <DamageData>();
                        pooledDamageData.SetDamage(this, damageAmount, hitValue.point, -hitValue.normal, m_ImpactForce, m_ImpactForceFrames, 0, hitValue.collider);
                        var damageProcessorModule = hitGameObject.GetCachedComponent <DamageProcessorModule>();
                        if (damageProcessorModule != null)
                        {
                            damageProcessorModule.ProcessDamage(m_DamageProcessor, damageTarget, pooledDamageData);
                        }
                        else
                        {
                            if (m_DamageProcessor == null)
                            {
                                m_DamageProcessor = DamageProcessor.Default;
                            }
                            m_DamageProcessor.Process(damageTarget, pooledDamageData);
                        }
                        GenericObjectPool.Return(pooledDamageData);
                    }
                    else if (m_ImpactForce > 0)
                    {
                        // If the damage target exists it will apply a force to the rigidbody in addition to procesing the damage. Otherwise just apply the force to the rigidbody.
                        var collisionRigidbody = hitGameObject.GetCachedParentComponent <Rigidbody>();
                        if (collisionRigidbody != null && !collisionRigidbody.isKinematic)
                        {
                            collisionRigidbody.AddForceAtPosition(m_ImpactForce * MathUtility.RigidbodyForceMultiplier * -hitValue.normal, hitValue.point);
                        }
                        else
                        {
                            var forceObject = hitGameObject.GetCachedParentComponent <IForceObject>();
                            if (forceObject != null)
                            {
                                forceObject.AddForce(m_Transform.forward * m_ImpactForce);
                            }
                        }
                    }
                }

                // An optional state can be activated on the hit object.
                if (!string.IsNullOrEmpty(m_ImpactStateName))
                {
                    StateManager.SetState(hitGameObject, m_ImpactStateName, true);
                    // If the timer isn't -1 then the state should be disabled after a specified amount of time. If it is -1 then the state
                    // will have to be disabled manually.
                    if (m_ImpactStateDisableTimer != -1)
                    {
                        StateManager.DeactivateStateTimer(hitGameObject, m_ImpactStateName, m_ImpactStateDisableTimer);
                    }
                }
            }

            // The object can destroy itself after a small delay.
            if (m_DestroyEvent == null && (m_DestroyOnCollision || forceDestruct || destructionDelay > 0))
            {
                m_DestroyEvent = SchedulerBase.ScheduleFixed(destructionDelay, Destruct, hit);
            }
        }
示例#23
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)
        {
            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)
                {
                    var damageTarget = DamageUtility.GetDamageTarget(m_CollidersHit[i].gameObject);
                    if (damageTarget != null)
                    {
                        // If the Damage Target 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.
                        var pooledDamageData = GenericObjectPool.Get <DamageData>();
                        var damageModifier   = Mathf.Max(1 - (hitDirection.magnitude / m_Radius), 0.01f);
                        pooledDamageData.SetDamage(hitDamageAmount * damageModifier, m_Transform.position, hitDirection.normalized, impactForce * damageModifier, impactForceFrames, m_Radius, originator, this, null);
                        if (m_DamageProcessor == null)
                        {
                            m_DamageProcessor = DamageProcessor.Default;
                        }
                        m_DamageProcessor.Process(damageTarget, pooledDamageData);
                        GenericObjectPool.Return(pooledDamageData);
                    }
                    else if (forceObject != null)
                    {
                        var damageModifier = Mathf.Max(1 - (hitDirection.magnitude / m_Radius), 0.01f);
                        forceObject.AddForce(impactForce * damageModifier * hitDirection.normalized);
                    }
                    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);

            m_DestructionEvent = SchedulerBase.Schedule(m_Lifespan, Destroy);
        }
示例#24
0
 public override void ReturnToPool()
 {
     Clear();
     Radius = 0;
     Pool.Return(this);
 }
示例#25
0
        private void RecalculateNormals(Mesh mesh, float angle, int[] triangles, Vector3[] vertices, bool instant = false)
        {
            if (triangles == null)
            {
                if (meshInfoCache == null)
                {
                    meshInfoCache = new Dictionary <Mesh, KeyValuePair <int[], Vector3[]> >();
                }
                if (meshInfoCache.ContainsKey(mesh))
                {
                    triangles = meshInfoCache[mesh].Key;
                    vertices  = meshInfoCache[mesh].Value;
                }
                else
                {
                    triangles = mesh.GetTriangles(0);
                    vertices  = mesh.vertices;
                    meshInfoCache.Add(mesh, new KeyValuePair <int[], Vector3[]>(triangles, vertices));
                }
            }
            var triNormals = AllocatedArray <Vector3> .Get(triangles.Length / 3);

            var normals = AllocatedArray <Vector3> .Get(vertices.Length);

            angle = angle * Mathf.Deg2Rad;

            var dictionary = PooledDictionary <Vector3, VertexEntry> .Get(vertices.Length, VectorComparer);

            //Goes through all the triangles and gathers up data to be used later
            for (var i = 0; i < triangles.Length; i += 3)
            {
                int i1 = triangles[i];
                int i2 = triangles[i + 1];
                int i3 = triangles[i + 2];

                //Calculate the normal of the triangle
                Vector3 p1       = vertices[i2] - vertices[i1];
                Vector3 p2       = vertices[i3] - vertices[i1];
                Vector3 normal   = Vector3.Cross(p1, p2).normalized;
                int     triIndex = i / 3;
                triNormals[triIndex] = normal;

                VertexEntry entry;
                //VertexKey key;

                //For each of the three points of the triangle
                //  > Add this triangle as part of the triangles they're connected to.

                if (!dictionary.TryGetValue(vertices[i1], out entry))
                {
                    entry = GenericObjectPool <VertexEntry> .Get();

                    entry.PopulateArrays();
                    dictionary.Add(vertices[i1], entry);
                }
                entry.Add(i1, triIndex);

                if (!dictionary.TryGetValue(vertices[i2], out entry))
                {
                    entry = GenericObjectPool <VertexEntry> .Get();

                    entry.PopulateArrays();
                    dictionary.Add(vertices[i2], entry);
                }
                entry.Add(i2, triIndex);

                if (!dictionary.TryGetValue(vertices[i3], out entry))
                {
                    entry = GenericObjectPool <VertexEntry> .Get();

                    entry.PopulateArrays();
                    dictionary.Add(vertices[i3], entry);
                }
                entry.Add(i3, triIndex);
            }

            foreach (var kvp in dictionary)
            {
                var value = kvp.Value;
                for (var i = 0; i < value.Count; ++i)
                {
                    var sum = new Vector3();
                    for (var j = 0; j < value.Count; ++j)
                    {
                        if (value.VertexIndex[i] == value.VertexIndex[j])
                        {
                            sum += triNormals[value.TriangleIndex[j]];
                        }
                        else
                        {
                            float dot = Vector3.Dot(
                                triNormals[value.TriangleIndex[i]],
                                triNormals[value.TriangleIndex[j]]);
                            dot = Mathf.Clamp(dot, -0.99999f, 0.99999f);
                            float acos = Mathf.Acos(dot);
                            if (acos <= angle)
                            {
                                sum += triNormals[value.TriangleIndex[j]];
                            }
                        }
                    }
                    normals[value.VertexIndex[i]] = sum.normalized;
                }
                value.Clear();
                GenericObjectPool <VertexEntry> .Return(value);
            }
            dictionary.ReturnToPool();
            if (instant == false)
            {
                if (mainThreadActions == null)
                {
                    mainThreadActions = new Queue <System.Action>();
                }
                mainThreadActions.Enqueue(() =>
                {
                    if (mesh)
                    {
                        mesh.normals = normals;
                    }
                    AllocatedArray <Vector3> .Return(normals, false);
                });
            }
            else
            {
                mesh.normals = normals;
                AllocatedArray <Vector3> .Return(normals, false);
            }
        }
示例#26
0
        /// <summary>
        /// Attaches the component to the specified character.
        /// </summary>
        /// <param name="character">The handler to attach the camera to.</param>
        protected virtual void OnAttachCharacter(GameObject character)
        {
            enabled = character != null && !m_CameraController.ActiveViewType.FirstPersonPerspective;

            // Disable the fade on the previous active character.
            if (m_CharacterFade)
            {
                if (m_Character != null && m_Character != character)
                {
                    DisableFades();

                    // Clear the previous mappings.
                    if (m_CharacterFadeMaterials != null)
                    {
                        if (m_CacheCharacterMaterials)
                        {
                            for (int i = 0; i < m_CharacterFadeMaterials.Length; ++i)
                            {
                                if (!m_OriginalMaterialValuesMap.ContainsKey(m_CharacterFadeMaterials[i]))
                                {
                                    continue;
                                }
                                GenericObjectPool.Return(m_OriginalMaterialValuesMap[m_CharacterFadeMaterials[i]]);
                                m_OriginalMaterialValuesMap.Remove(m_CharacterFadeMaterials[i]);
                            }
                        }
                        m_CharacterFadeMaterials = null;
                    }
                    m_OriginalMaterialValuesMap.Clear();

                    EventHandler.UnregisterEvent <bool>(m_Character, "OnCameraChangePerspectives", OnChangePerspectives);
                    EventHandler.UnregisterEvent <bool, bool>(m_Character, "OnCharacterIndependentFade", OnIndependentFade);
                    EventHandler.UnregisterEvent <Item>(m_Character, "OnInventoryAddItem", OnAddItem);
                    EventHandler.UnregisterEvent <GameObject, bool>(m_Character, "OnShootableWeaponShowProjectile", OnShowProjectile);
                    EventHandler.UnregisterEvent(m_Character, "OnRespawn", OnRespawn);
                }
            }

            m_Character = character;

            if (m_Character != null)
            {
                m_CharacterTransform    = m_Character.transform;
                m_CharacterLocomotion   = m_Character.GetCachedComponent <UltimateCharacterLocomotion>();
                m_CharacterLayerManager = m_Character.GetCachedComponent <CharacterLayerManager>();
                if (m_CharacterFade)
                {
                    // Determine the number of renderers that will be faded so their materials can be cached.
                    m_RegisteredMaterial.Clear();
                    var count     = 0;
                    var renderers = m_Character.GetComponentsInChildren <Renderer>(true);
                    for (int i = 0; i < renderers.Length; ++i)
                    {
                        // The renderer fade can be ignored.
                        if (renderers[i].gameObject.GetCachedComponent <IgnoreFadeIdentifier>() != null)
                        {
                            continue;
                        }
                        var materials = renderers[i].materials;
                        for (int j = 0; j < materials.Length; ++j)
                        {
                            if (materials[j].HasProperty(m_ColorID))
                            {
                                count++;
                            }
                        }
                    }

                    if (count > 0)
                    {
                        if (m_CharacterFadeMaterials == null)
                        {
                            m_CharacterFadeMaterials = new Material[count];
                        }
                        else if (m_CharacterFadeMaterials.Length != count)
                        {
                            if (m_CacheCharacterMaterials)
                            {
                                // The mapping may exist from a previous character.
                                for (int i = 0; i < m_CharacterFadeMaterials.Length; ++i)
                                {
                                    GenericObjectPool.Return(m_OriginalMaterialValuesMap[m_CharacterFadeMaterials[i]]);
                                    m_OriginalMaterialValuesMap.Remove(m_CharacterFadeMaterials[i]);
                                }
                            }
                            System.Array.Resize(ref m_CharacterFadeMaterials, count);
                        }

                        // Cache a reference to all of the faded materials.
                        m_CharacterFadeMaterialsCount = 0;
                        for (int i = 0; i < renderers.Length; ++i)
                        {
                            // The renderer fade can be ignored.
                            if (renderers[i].gameObject.GetCachedComponent <IgnoreFadeIdentifier>() != null)
                            {
                                continue;
                            }

                            var materials = renderers[i].materials;
                            for (int j = 0; j < materials.Length; ++j)
                            {
                                if (m_RegisteredMaterial.Contains(materials[j]))
                                {
                                    continue;
                                }
                                if (materials[j].HasProperty(m_ColorID))
                                {
                                    if (materials[j].HasProperty(OriginalMaterialValue.ModeID))
                                    {
                                        m_MaterialModeSet.Add(materials[j]);
                                    }
                                    m_CharacterFadeMaterials[m_CharacterFadeMaterialsCount] = materials[j];
                                    m_RegisteredMaterial.Add(materials[j]);
                                    m_CharacterFadeMaterialsCount++;

                                    if (m_CacheCharacterMaterials)
                                    {
                                        var originalMaterialValues = GenericObjectPool.Get <OriginalMaterialValue>();
                                        originalMaterialValues.Initialize(materials[j], m_ColorID, m_MaterialModeSet.Contains(materials[j]));
                                        m_OriginalMaterialValuesMap.Add(materials[j], originalMaterialValues);
                                    }
                                }
                            }
                        }
                    }

                    EventHandler.RegisterEvent <bool>(m_Character, "OnCameraChangePerspectives", OnChangePerspectives);
                    EventHandler.RegisterEvent <Item>(m_Character, "OnInventoryAddItem", OnAddItem);
                    EventHandler.RegisterEvent <GameObject, bool>(m_Character, "OnShootableWeaponShowProjectile", OnShowProjectile);
                    EventHandler.RegisterEvent <bool, bool>(m_Character, "OnCharacterIndependentFade", OnIndependentFade);
                    EventHandler.RegisterEvent(m_Character, "OnRespawn", OnRespawn);
                }

                // Fade the obstructing objects immediately after the character has been assigned.
                if (m_ObstructingObjectsFade)
                {
                    FadeObstructingObjects(true);
                }
            }
        }
 public void ReturnToPool()
 {
     Pool.Return(this);
 }