Ejemplo n.º 1
0
        /// <summary>
        /// The ability has started.
        /// </summary>
        protected override void AbilityStarted()
        {
            // If a handler exists then the ability is interested in updates when the axis value changes. This for example allows the lean to switch
            // between the left and right lean without having to stop and start again.
            if (m_Handler != null)
            {
                m_LeanInput = GenericObjectPool.Get <ActiveInputEvent>();
                m_LeanInput.Initialize(ActiveInputEvent.Type.Axis, InputNames[InputIndex], "OnLeanInputUpdate");
                m_Handler.RegisterInputEvent(m_LeanInput);
            }
            EventHandler.RegisterEvent <float>(m_GameObject, "OnLeanInputUpdate", OnInputUpdate);

            base.AbilityStarted();

            // The collider should be activated when the ability starts. The collider detects when the character would be clipping with a wall
            // and also allows the character to be shot at while leaning.
            if (m_ColliderGameObject != null)
            {
                m_ColliderGameObject.SetActive(true);
            }

            // Start leaning.
            m_AxisValue = InputAxisValue;
            UpdateLean(true);
        }
Ejemplo n.º 2
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);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initialize the default values.
        /// </summary>
        public override void Awake()
        {
            base.Awake();

            m_Handler = m_GameObject.GetCachedComponent <UltimateCharacterLocomotionHandler>();

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

                m_StopRotateInputEvent = GenericObjectPool.Get <ActiveInputEvent>();
                m_StopRotateInputEvent.Initialize(ActiveInputEvent.Type.ButtonUp, m_RotateInputName, "OnRPGMovementTypeStopRotate");

                m_TurnInputEvent = GenericObjectPool.Get <ActiveInputEvent>();
                m_TurnInputEvent.Initialize(ActiveInputEvent.Type.Axis, m_TurnInputName, "OnRPGMovementTypeTurn");

                m_AutoMoveInputEvent = GenericObjectPool.Get <ActiveInputEvent>();
                m_AutoMoveInputEvent.Initialize(ActiveInputEvent.Type.ButtonDown, m_AutoMoveInputName, "OnRPGMovementTypeAutoMove");

                m_Handler.RegisterInputEvent(m_StartRotateInputEvent);
                m_Handler.RegisterInputEvent(m_TurnInputEvent);
                m_Handler.RegisterInputEvent(m_AutoMoveInputEvent);
            }
            EventHandler.RegisterEvent(m_GameObject, "OnRPGMovementTypeStartRotate", OnStartRotate);
            EventHandler.RegisterEvent(m_GameObject, "OnRPGMovementTypeStopRotate", OnStopRotate);
            EventHandler.RegisterEvent <float>(m_GameObject, "OnRPGMovementTypeTurn", OnTurn);
            EventHandler.RegisterEvent(m_GameObject, "OnRPGMovementTypeAutoMove", OnToggleAutoMove);
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
            /// <summary>
            /// Initializes the object.
            /// </summary>
            /// <param name="characterLocomotion">The character that is being managed by the KinematicObjectManager.</param>
            public void Initialize(UltimateCharacterLocomotion characterLocomotion)
            {
                m_CharacterLocomotion = characterLocomotion;

                OnAttachLookSource(m_CharacterLocomotion.LookSource);
                EventHandler.RegisterEvent <ILookSource>(m_CharacterLocomotion.gameObject, "OnCharacterAttachLookSource", OnAttachLookSource);
                EventHandler.RegisterEvent <bool>(m_CharacterLocomotion.gameObject, "OnCharacterChangeUpdateLocation", OnChangeUpdateLocation);

                // The class is pooled so reset any variables.
                m_HorizontalMovement = m_ForwardMovement = m_DeltaYawRotation = 0;
                Initialize(characterLocomotion.transform);

                m_CharacterHandler = m_CharacterLocomotion.GetComponent <UltimateCharacterLocomotionHandler>();
                m_CharacterIK      = m_CharacterLocomotion.GetComponent <CharacterIKBase>();

                // Wait a moment before finishing with the initialization. This allows the character to be created at runtime.
                m_CompleteInitEvent = Scheduler.ScheduleFixed(Time.fixedDeltaTime / 2, () => {
                    if (m_CharacterHandler == null)
                    {
                        m_CharacterHandler = m_CharacterLocomotion.GetComponent <UltimateCharacterLocomotionHandler>();
                    }
                    if (m_CharacterIK == null)
                    {
                        m_CharacterIK = m_CharacterLocomotion.GetComponent <CharacterIKBase>();
                    }

                    var smoothedBones = m_CharacterLocomotion.SmoothedBones;
                    if (smoothedBones != null && smoothedBones.Length > 0)
                    {
                        var validBones = 0;
                        for (int i = 0; i < smoothedBones.Length; ++i)
                        {
                            if (smoothedBones[i] != null)
                            {
                                validBones++;
                            }
                        }
                        if (validBones > 0)
                        {
                            m_SmoothedBones = new SmoothFixedLocation[validBones];
                            var index       = 0;
                            for (int i = 0; i < smoothedBones.Length; ++i)
                            {
                                if (smoothedBones[i] == null)
                                {
                                    continue;
                                }
                                m_SmoothedBones[index] = GenericObjectPool.Get <SmoothFixedLocation>();
                                m_SmoothedBones[index].Initialize(smoothedBones[i]);
                                index++;
                            }
                        }
                    }
                    m_CompleteInitEvent = null;
                });
            }
Ejemplo n.º 6
0
 /// <summary>
 /// Internal method which registers the character to be managed by the KinematicObjectManager.
 /// </summary>
 /// <param name="characterLocomotion">The character that should be managed by the KinematicObjectManager.</param>
 /// <returns>The index of the character registered.</returns>
 private int RegisterCharacterInternal(UltimateCharacterLocomotion characterLocomotion)
 {
     if (m_CharacterCount == m_Characters.Length)
     {
         System.Array.Resize(ref m_Characters, m_Characters.Length + 1);
         Debug.LogWarning($"Characters array resized. For best performance increase the size of the Start Character Count variable " +
                          $"within the Kinematic Object Manager to a value of at least {(m_CharacterCount + 1)}.");
     }
     m_Characters[m_CharacterCount] = GenericObjectPool.Get <KinematicCharacter>();
     m_Characters[m_CharacterCount].Initialize(characterLocomotion);
     m_CharacterCount++;
     return(m_CharacterCount - 1);
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Intenral method which registers the camera to be managed by the KinematicObjectManager.
 /// </summary>
 /// <param name="cameraController">The camera that should be managed by the KinematicObjectManager.</param>
 /// <returns>The index of the camera registered.</returns>
 private int RegisterCameraInternal(CameraController cameraController)
 {
     if (m_CameraCount == m_Cameras.Length)
     {
         System.Array.Resize(ref m_Cameras, m_Cameras.Length + 1);
         Debug.LogWarning($"Cameras array resized. For best performance increase the size of the Start Camera Count variable " +
                          $"within the Kinematic Object Manager to a value of at least {(m_CameraCount + 1)}.");
     }
     m_Cameras[m_CameraCount] = GenericObjectPool.Get <KinematicCamera>();
     m_Cameras[m_CameraCount].Initialize(cameraController);
     m_CameraCount++;
     return(m_CameraCount - 1);
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Internal method which registers the kinematic object that should be managed by the KinematicObjectManager.
 /// </summary>
 /// <param name="kinematicObject">The kinematic object that should be managed by the KinematicObjectManager.</param>
 /// <returns>The index of the kinematci object registered.</returns>
 private int RegisterKinematicObjectInternal(IKinematicObject kinematicObject)
 {
     if (m_KinematicObjectCount == m_KinematicObjects.Length)
     {
         System.Array.Resize(ref m_KinematicObjects, m_KinematicObjects.Length + 1);
         Debug.LogWarning($"Kinematic objects array resized. For best performance increase the size of the Start Kinematic Object Count variable " +
                          $"within the Kinematic Object Manager to a value of at least {(m_KinematicObjectCount + 1)}.");
     }
     m_KinematicObjects[m_KinematicObjectCount] = GenericObjectPool.Get <KinematicObject>();
     m_KinematicObjects[m_KinematicObjectCount].Initialize(kinematicObject);
     m_KinematicObjectCount++;
     return(m_KinematicObjectCount - 1);
 }
Ejemplo n.º 9
0
        public TimerInstance AddTimer(
            float intervalInSec,
            float totalInSec,
            TimerEventHandler intervalCallback,
            TimerEventHandler endCallback,
            object userdata)
        {
            int index = m_IndexCreator.NextID;

            TimerTask task = m_TaskPool.Get();

            task.SetData(index, intervalInSec, totalInSec, intervalCallback, endCallback, userdata);

            return(AddTask(task, null));
        }
Ejemplo n.º 10
0
        public void SendMessage(int messageID, MessageCompressType compressType, MessageCryptoType cryptoType, byte[] dataBytes)
        {
            lock (cachedWillSendMessageLocker)
            {
                var willSendMessage = willSendMessagePool.Get();
                willSendMessage.ID           = messageID;
                willSendMessage.CompressType = compressType;
                willSendMessage.CryptoType   = cryptoType;
                willSendMessage.DataBytes    = dataBytes;

                cachedWillSendMessages.Add(willSendMessage);
            }

            DoSend();
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Enables fading on the renderers.
        /// </summary>
        private void EnableRendererFade()
        {
            // Fade all of the active renderers.
            var renderers = m_Character.GetComponentsInChildren <Renderer>(false);

            for (int i = 0; i < renderers.Length; ++i)
            {
                // The 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)
                {
                    var material = materials[j];
                    if (m_ActiveMaterials.Contains(material) || !material.HasProperty(m_ColorID))
                    {
                        continue;
                    }

                    m_Materials.Add(material);
                    m_ActiveMaterials.Add(material);

                    // Cache the original values so they can be reverted.
                    var originalMaterialValues = GenericObjectPool.Get <OriginalMaterialValue>();
                    originalMaterialValues.Initialize(material, m_ColorID, material.HasProperty(OriginalMaterialValue.ModeID));
                    m_OriginalMaterialValuesMap.Add(material, originalMaterialValues);

                    // The material should be able to fade.
                    material.SetFloat(OriginalMaterialValue.ModeID, 2);
                    material.SetInt(OriginalMaterialValue.SrcBlendID, (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                    material.SetInt(OriginalMaterialValue.DstBlendID, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                    material.EnableKeyword(OriginalMaterialValue.AlphaBlendString);
                    material.renderQueue = 3000;

                    // If the action is already active then the material is being faded when the perspective is switching. Set the alpha to the
                    // same alpha value as the rest of the materials.
                    if (m_Active)
                    {
                        var color = material.GetColor(m_ColorID);
                        color.a = m_Materials[0].GetColor(m_ColorID).a;
                        material.SetColor(m_ColorID, color);
                    }
                }
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// The object has taken damage.
        /// </summary>
        /// <param name="amount">The amount of damage taken.</param>
        /// <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 did the damage.</param>
        /// <param name="hitCollider">The Collider that was hit.</param>
        private void OnDamage(float amount, Vector3 position, Vector3 force, GameObject attacker, Collider hitCollider)
        {
            // Don't show a hit indicator if the force is 0 or there is no attacker. This prevents damage such as fall damage from showing the damage indicator.
            if ((!m_AlwaysShowIndicator && force.sqrMagnitude == 0) || attacker == null || m_ActiveDamageIndicatorCount == m_ActiveDamageIndicators.Length)
            {
                return;
            }

            var attackerPosition = (m_FollowAttacker && m_CharacterTransform != attacker) ? attacker.transform.position : position;

            // Adjust the hit position.
            var localHitPosition = attacker.transform.InverseTransformPoint(position);

            localHitPosition.x = localHitPosition.z = 0;
            attackerPosition  += attacker.transform.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;

            // Determine the angle of the damage position to determine if a new damage indicator should be shown.
            var angle = Vector2.SignedAngle(centerScreenPoint, Vector2.right);

            // Do not show a new damage indicator if the angle is less than a threshold compared to the already displayed indicators.
            DamageIndicator damageIndicator;

            for (int i = 0; i < m_ActiveDamageIndicatorCount; ++i)
            {
                damageIndicator = m_ActiveDamageIndicators[i];
                if (Mathf.Abs(angle - damageIndicator.Angle) < m_IndicatorAngleThreshold)
                {
                    damageIndicator.DisplayTime = Time.time;
                    m_ActiveDamageIndicators[i] = damageIndicator;
                    return;
                }
            }

            // Add the indicator to the active hit indicators list and enable the component.
            damageIndicator = GenericObjectPool.Get <DamageIndicator>();
            damageIndicator.Initialize(attacker.transform, position, angle, m_StoredIndicators[m_DamageIndicatorIndex]);
            m_ActiveDamageIndicators[m_ActiveDamageIndicatorCount] = damageIndicator;
            m_ActiveDamageIndicatorCount++;
            m_DamageIndicatorIndex = (m_DamageIndicatorIndex + 1) % m_StoredIndicators.Length;

            // Allow the indicators to move/fade.
            m_GameObject.SetActive(true);
        }
Ejemplo n.º 13
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);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// The ability has started.
        /// </summary>
        protected override void AbilityStarted()
        {
            m_ApplyHoldForce = true;
            m_HoldForce      = 0;

            // If the jump has already been applied then it is a repeated jump.
            if (m_JumpApplied)
            {
                OnAirborneJump();
            }
            else
            {
                if (!m_JumpEvent.WaitForAnimationEvent || m_ForceImmediateJump)
                {
                    Scheduler.ScheduleFixed(m_ForceImmediateJump ? 0 : m_JumpEvent.Duration, ApplyJumpForce);
                }
            }

            if (m_ForceHold > 0)
            {
                if (m_Handler != null && InputIndex != -1)
                {
                    m_HoldInput = GenericObjectPool.Get <ActiveInputEvent>();
                    m_HoldInput.Initialize(ActiveInputEvent.Type.ButtonUp, InputNames[InputIndex], "OnJumpAbilityReleaseHold");
                    m_Handler.RegisterInputEvent(m_HoldInput);
                }
                EventHandler.RegisterEvent(m_GameObject, "OnJumpAbilityReleaseHold", OnReleaseHold);
            }

            // The character can do a repeated jump after the character is already in the air.
            if (!m_AirborneJumpRegistered)
            {
                if (m_Handler != null && InputIndex != -1)
                {
                    m_AirborneJumpInput = GenericObjectPool.Get <ActiveInputEvent>();
                    m_AirborneJumpInput.Initialize(ActiveInputEvent.Type.ButtonDown, InputNames[InputIndex], "OnJumpAbilityAirborneJump");
                    m_Handler.RegisterInputEvent(m_AirborneJumpInput);
                }
                EventHandler.RegisterEvent(m_GameObject, "OnJumpAbilityAirborneJump", OnPerformAirborneJump);
                m_AirborneJumpRegistered = true;
            }
            m_ForceImmediateJump = false;

            base.AbilityStarted();
        }
Ejemplo n.º 15
0
    public virtual void DoFixedUpdate()
    {
        //TODO moveStep skillStep etc...
        unitFrameInfo = GenericObjectPool <UnitFrameInfo> .Get();

        unitFrameInfo.frame     = FrameManager.currentNetworkFrame;
        unitFrameInfo.canMove   = canMove;
        unitFrameInfo.canRotate = canRotation;
        if (canMove)
        {
            unitFrameInfo.position = position;
        }
        if (canRotation)
        {
            unitFrameInfo.rotation = rotation;
        }
        Debug.Log("DoFixedUpdate...");
    }
Ejemplo n.º 16
0
        /// <summary>
        /// Updates the shader to support a fade.
        /// </summary>
        /// <param name="material">The material to update.</param>
        private void EnableFadeMaterial(Material material)
        {
            // If the character's materials change at runtime then the values need to be saved every time fading is enabled.
            if (!m_CacheCharacterMaterials && !m_OriginalMaterialValuesMap.ContainsKey(material))
            {
                var originalMaterialValues = GenericObjectPool.Get <OriginalMaterialValue>();
                originalMaterialValues.Initialize(material, m_ColorID, m_MaterialModeSet.Contains(material));
                m_OriginalMaterialValuesMap.Add(material, originalMaterialValues);
            }

            if (m_MaterialModeSet.Contains(material))
            {
                material.SetFloat(OriginalMaterialValue.ModeID, 2);
                material.SetInt(OriginalMaterialValue.SrcBlendID, (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt(OriginalMaterialValue.DstBlendID, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
            }
            material.EnableKeyword(OriginalMaterialValue.AlphaBlendString);
            material.renderQueue = 3000;
        }
Ejemplo n.º 17
0
        /// <summary>
        /// The object has taken damage.
        /// </summary>
        /// <param name="amount">The amount of damage taken.</param>
        /// <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 did the damage.</param>
        /// <param name="hitCollider">The Collider that was hit.</param>
        private void OnDamage(float amount, Vector3 position, Vector3 force, GameObject attacker, Collider hitCollider)
        {
            // Don't show a hit indicator if the force is 0 or there is no attacker. This prevents damage such as fall damage from showing the damage indicator.
            if ((!m_AlwaysShowIndicator && force.sqrMagnitude == 0) || attacker == null || m_ActiveDamageIndicatorCount == m_ActiveDamageIndicators.Length)
            {
                return;
            }

            var direction = Vector3.ProjectOnPlane(m_CharacterTransform.position - ((m_FollowAttacker && m_Character != attacker) ? attacker.transform.position : 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();

            // Determine the angle of the damage position to determine if a new damage indicator should be shown.
            var angle = Vector3.Angle(direction, m_CameraTransform.forward) * Mathf.Sign(Vector3.Dot(direction, m_CameraTransform.right));

            // Do not show a new damage indicator if the angle is less than a threshold compared to the already displayed indicators.
            DamageIndicator damageIndicator;

            for (int i = 0; i < m_ActiveDamageIndicatorCount; ++i)
            {
                damageIndicator = m_ActiveDamageIndicators[i];
                if (Mathf.Abs(angle - damageIndicator.Angle) < m_IndicatorAngleThreshold)
                {
                    damageIndicator.DisplayTime = Time.time;
                    m_ActiveDamageIndicators[i] = damageIndicator;
                    return;
                }
            }

            // Add the indicator to the active hit indicators list and enable the component.
            damageIndicator = GenericObjectPool.Get <DamageIndicator>();
            damageIndicator.Initialize(attacker.transform, position, angle, m_StoredIndicators[m_DamageIndicatorIndex]);
            m_ActiveDamageIndicators[m_ActiveDamageIndicatorCount] = damageIndicator;
            m_ActiveDamageIndicatorCount++;
            m_DamageIndicatorIndex = (m_DamageIndicatorIndex + 1) % m_StoredIndicators.Length;

            // Allow the indicators to move/fade.
            m_GameObject.SetActive(true);
        }
Ejemplo n.º 18
0
        private void OnReceived(object sender, ReceiveEventArgs e)
        {
            lock (m_MessageLocker)
            {
                ServerLogMessage message = m_MessagePool.Get();

                int    id           = BitConverter.ToInt32(e.bytes, 0);
                byte[] contentBytes = new byte[0];
                if (e.bytes.Length > sizeof(int))
                {
                    contentBytes = new byte[e.bytes.Length - sizeof(int)];
                    Array.Copy(e.bytes, sizeof(int), contentBytes, 0, contentBytes.Length);
                }
                message.ID      = id;
                message.Client  = e.client;
                message.Message = contentBytes;

                m_ReceivedMessages.Add(message);
            }
        }
Ejemplo n.º 19
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);
         }
     }
 }
Ejemplo n.º 20
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);
        }
Ejemplo n.º 21
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);
            }
        }
Ejemplo n.º 22
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);
        }
Ejemplo n.º 23
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);
            }
        }
Ejemplo n.º 24
0
 internal static List <IQuadObject> GetObjectList()
 {
     return(sm_ObjectListPool.Get());
 }
Ejemplo n.º 25
0
 internal static List <QuadNode> GetNodeList()
 {
     return(sm_NodeListPool.Get());
 }
Ejemplo n.º 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);
                }
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Fade any objects that get in the way between the character and the camera.
        /// </summary>
        /// <param name="immediateFade">Should the fade material be changed immediately?</param>
        private void FadeObstructingObjects(bool immediateFade)
        {
            if (!m_ObstructingObjectsFade)
            {
                return;
            }

            // Disable any obstructing colliders so the sphere cast can detect which objects are obstructing.
            for (int i = 0; i < m_ObstructingCollidersCount; ++i)
            {
                m_ObstructingColliders[i].enabled = true;
            }
            m_ObstructingCollidersCount = 0;

            var characterPosition = m_CharacterTransform.TransformPoint(m_TransformOffset);
            var direction         = (m_Transform.position - characterPosition);
            var start             = characterPosition - direction.normalized * m_CollisionRadius;

            m_CharacterLocomotion.EnableColliderCollisionLayer(false);
            // Fire a sphere to prevent the camera from colliding with other objects.
            var hitCount = Physics.SphereCastNonAlloc(start, m_CollisionRadius, direction.normalized, m_RaycastsHit,
                                                      direction.magnitude, m_CharacterLayerManager.IgnoreInvisibleCharacterWaterLayers, QueryTriggerInteraction.Ignore);

            m_CharacterLocomotion.EnableColliderCollisionLayer(true);

            m_ObstructionHitSet.Clear();
            if (hitCount > 0)
            {
                // Loop through all of the hit colliders. For any collider that has been hit get all of the renderers. The materials that are used on the
                // renderers then need to be checked to determine if they can be faded. If the material can be faded place it in a set which will then
                // be checked in the next block to determine if the material should be faded.
                for (int i = 0; i < hitCount; ++i)
                {
                    var renderers   = m_RaycastsHit[i].transform.gameObject.GetCachedComponents <Renderer>();
                    var obstructing = false;
                    for (int j = 0; j < renderers.Length; ++j)
                    {
                        var materials = renderers[j].materials;
                        for (int k = 0; k < materials.Length; ++k)
                        {
                            if (!m_CanObstructionFade.TryGetValue(materials[k], out var canFade))
                            {
                                // Objects can fade if they have the color property and can be transparent.
                                canFade = materials[k].HasProperty(m_ColorID) && (m_AutoSetMode || materials[k].renderQueue >= (int)UnityEngine.Rendering.RenderQueue.Transparent);
                                m_CanObstructionFade.Add(materials[k], canFade);
                            }

                            if (canFade)
                            {
                                var material = materials[k];
                                // Any material contained within the hit set should be faded.
                                m_ObstructionHitSet.Add(material);
                                if (m_DisableCollider && !obstructing)
                                {
                                    obstructing = CanMaterialFade(material);
                                }

                                // The same material may be applied to multiple renderers.
                                if (!m_OriginalMaterialValuesMap.ContainsKey(material))
                                {
                                    // Don't set the mode automatically just because it has the property - not all objects in the environment should fade.
                                    if (m_AutoSetMode && material.HasProperty(OriginalMaterialValue.ModeID))
                                    {
                                        m_MaterialModeSet.Add(material);
                                    }
                                    var originalMaterialValues = GenericObjectPool.Get <OriginalMaterialValue>();
                                    originalMaterialValues.Initialize(material, m_ColorID, m_MaterialModeSet.Contains(material));
                                    m_OriginalMaterialValuesMap.Add(material, originalMaterialValues);

                                    m_ObstructingMaterials[m_ObstructingMaterialsCount] = material;
                                    m_ObstructingMaterialsCount++;

                                    EnableFadeMaterial(material);
                                }
                            }
                        }
                    }

                    // If the object is faded then the collider has the option of being disabled to prevent it from causing collisions.
                    if (m_DisableCollider && obstructing)
                    {
                        m_RaycastsHit[i].collider.enabled = false;
                        m_ObstructingColliders[m_ObstructingCollidersCount] = m_RaycastsHit[i].collider;
                        m_ObstructingCollidersCount++;
                    }
                }
            }

            // Once the obstructing objects have been found they should be faded. Note that this can cause a lot of overdraw so the FadeObject method can be
            // overridden to provide a custom effect such as the one described on https://madewith.unity.com/stories/dissolving-the-world-part-1.
            for (int i = m_ObstructingMaterialsCount - 1; i >= 0; --i)
            {
                if (!FadeMaterial(m_ObstructingMaterials[i], m_ObstructionHitSet.Contains(m_ObstructingMaterials[i]), immediateFade))
                {
                    RemoveObstructingMaterial(i);
                }
            }
        }
Ejemplo n.º 28
0
 public static ShapeList New()
 {
     return(Pool.Get());
 }
Ejemplo n.º 29
0
 public static EventDispatcher GetDispatcher()
 {
     return(sm_DispatcherPool.Get());
 }
Ejemplo n.º 30
0
        /// <summary>
        /// Initializes the materials on the renderers for character fade.
        /// </summary>
        /// <param name="renderers">The renderers that should be initilaizes for character fade.</param>
        private void InitializeCharacterFadeRenderers(Renderer[] renderers)
        {
            var count = 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]) && materials[j].HasProperty(m_ColorID))
                    {
                        count++;
                    }
                }
            }

            if (count > 0)
            {
                var totalCount = m_CharacterFadeMaterialsCount + count;
                if (m_CharacterFadeMaterials == null)
                {
                    m_CharacterFadeMaterials = new Material[totalCount];
                }
                else if (totalCount >= m_CharacterFadeMaterials.Length)
                {
                    System.Array.Resize(ref m_CharacterFadeMaterials, totalCount);
                }

                // Cache a reference to all of the faded materials.
                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]) && 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 && !m_OriginalMaterialValuesMap.ContainsKey(materials[j]))
                            {
                                var originalMaterialValues = GenericObjectPool.Get <OriginalMaterialValue>();
                                originalMaterialValues.Initialize(materials[j], m_ColorID, m_MaterialModeSet.Contains(materials[j]));
                                m_OriginalMaterialValuesMap.Add(materials[j], originalMaterialValues);
                            }
                        }
                    }
                }
            }
        }