/// --------------------------------------------- /// Ultimate Character Controller /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.UltimateCharacterController.Character.Abilities { using Opsive.UltimateCharacterController.Utility; using UnityEngine; /// /// The SpeedChange ability will update the controller's horizontal and forward movement values based on the multiplier. This value will then be used /// by the controller and Animator to change the character's speed. /// [AllowDuplicateTypes] [DefaultInputName("Change Speeds")] [DefaultStartType(AbilityStartType.ButtonDownContinuous)] [DefaultStopType(AbilityStopType.ButtonUp)] public class SpeedChange : Ability { [Tooltip("The speed multiplier when the ability is active.")] [SerializeField] protected float m_SpeedChangeMultiplier = 2; [Tooltip("The minimum value the SpeedChangeMultiplier can change the InputVector value to.")] [SerializeField] protected float m_MinSpeedChangeValue = -2; [Tooltip("The maximum value the SpeedChangeMultiplier can change the InputVector to.")] [SerializeField] protected float m_MaxSpeedChangeValue = 2; [Tooltip("Specifies the value to set the Speed Animator parameter to.")] [SerializeField] protected float m_SpeedParameter = 2; [Tooltip("Does the ability require movement in order to stay active?")] [SerializeField] protected bool m_RequireMovement = true; public float SpeedChangeMultiplier { get { return m_SpeedChangeMultiplier; } set { m_SpeedChangeMultiplier = value; } } public float MinSpeedChangeValue { get { return m_MinSpeedChangeValue; } set { m_MinSpeedChangeValue = value; } } public float MaxSpeedChangeValue { get { return m_MaxSpeedChangeValue; } set { m_MaxSpeedChangeValue = value; } } public float SpeedParameter { get { return m_SpeedParameter; } set { m_SpeedParameter = value; } } public bool RequireMovement { get { return m_RequireMovement; } set { m_RequireMovement = value; } } public override bool IsConcurrent { get { return true; } } /// /// Called when the ablity is tried to be started. If false is returned then the ability will not be started. /// /// True if the ability can be started. public override bool CanStartAbility() { // An attribute may prevent the ability from starting. if (!base.CanStartAbility()) { return false; } return !m_RequireMovement || m_CharacterLocomotion.Moving; } /// /// Should the input be checked to ensure button up is using the correct value? /// /// True if the input should be checked. protected override bool ShouldCheckInput() { return false; } /// /// The ability has started. /// protected override void AbilityStarted() { base.AbilityStarted(); if (m_SpeedParameter != -1) { SetSpeedParameter(m_SpeedParameter); } } /// /// Updates the ability. Applies a multiplier to the horizontal and forward movement values. /// public override void Update() { base.Update(); // If RequireMovement is true then the character must be moving in order for the ability to be active. if (m_RequireMovement && !m_CharacterLocomotion.Moving) { StopAbility(true); return; } var inputVector = m_CharacterLocomotion.InputVector; inputVector.x = Mathf.Clamp(inputVector.x * m_SpeedChangeMultiplier, m_MinSpeedChangeValue, m_MaxSpeedChangeValue); inputVector.y = Mathf.Clamp(inputVector.y * m_SpeedChangeMultiplier, m_MinSpeedChangeValue, m_MaxSpeedChangeValue); m_CharacterLocomotion.InputVector = inputVector; // The raw input vector should be updated as well. This allows other abilities to know if the character has a different speed. inputVector = m_CharacterLocomotion.RawInputVector; inputVector.x = Mathf.Clamp(inputVector.x * m_SpeedChangeMultiplier, m_MinSpeedChangeValue, m_MaxSpeedChangeValue); inputVector.y = Mathf.Clamp(inputVector.y * m_SpeedChangeMultiplier, m_MinSpeedChangeValue, m_MaxSpeedChangeValue); m_CharacterLocomotion.RawInputVector = inputVector; } /// /// The ability has stopped running. /// /// Was the ability force stopped? protected override void AbilityStopped(bool force) { base.AbilityStopped(force); SetSpeedParameter(0); } } }