Swift Dash Ability

Hey guys,

I have spent the last 2 days trying to create a Dash ability and while it mechanically works it's not as responsive as I want it to be.

The requirements: I want the player to be able to dash in the direction of the current input or look direction in case the player is only pressing "W" and I want to be able to dash 3 times in a row.

The problem: Lets say Im holding down "A" and I dash left then immediately hold down "D" to dash right what will happen is the character will dash left instead of right because the velocity has not built up enough to move right, but if I wait 1 second between each dash it works really well.

The perfect solution: I need a way to get the player velocity to its maximum (or desired velocity) possible as soon as the player changes key presses. I wont actually set that velocity to the player just need it for the dash direction.

My current code: (the backwards dash solution is not a good one but I put it as an experiment)

 
Instead of adding a force to the character, have you tried an ability that simply increases the character's movement speed for a fraction of a second? E.g. enabling a "Dash" state which increases the motor speed multiplier, then disabling it after X seconds.
 
Instead of adding a force to the character, have you tried an ability that simply increases the character's movement speed for a fraction of a second? E.g. enabling a "Dash" state which increases the motor speed multiplier, then disabling it after X seconds.

Do you mean something like this? I took this from the SpeedChange ability and added a timer to turn it off or distance away from the starting point.


C#:
    public class Dash : Ability
    {

        [SerializeField] private float _speedMultiplier = 15;
        [SerializeField] private float _minSpeedChangeValue = -15;
        [SerializeField] private float _maxSpeedChangeValue = 15;
        [SerializeField] private float _maxDistance = 7;
        [SerializeField] private float _maxTime = 0.2f;

        private float _startTime;

        private Vector3 _startPosition;
      
        public override bool CanStartAbility()
        {
            if (!base.CanStartAbility()) {
                return false;
            }

            return true;
        }

        protected override void AbilityStarted()
        {
            base.AbilityStarted();


            _startTime = Time.time;
            _startPosition = m_Transform.position;

        }

        public override void Update()
        {
            base.Update();

            if (Vector3.Distance(_startPosition, m_Transform.position) >  _maxDistance|| Time.time - _startTime > _maxTime)
            {
                StopAbility(true);
                return;
            }

          
            var inputVector = m_CharacterLocomotion.InputVector;
            inputVector.x = Mathf.Clamp(inputVector.x * _speedMultiplier, _minSpeedChangeValue, _maxSpeedChangeValue);
            inputVector.y = Mathf.Clamp(inputVector.y * _speedMultiplier, _minSpeedChangeValue, _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 * _speedMultiplier, _minSpeedChangeValue, _maxSpeedChangeValue);
            inputVector.y = Mathf.Clamp(inputVector.y * _speedMultiplier, _minSpeedChangeValue, _maxSpeedChangeValue);
            m_CharacterLocomotion.RawInputVector = inputVector;
        }
    }
 
Last edited:
That's definitely an option, but I would imagine a more reliable way would be to use the state system, e.g. by having the ability activate a certain state for X seconds, and having a state preset on the UltimateCharacterLocomotion component that increases the character's motion speed multiplier.
 
Top