Player Dodging State not moving

Hello again folks. So… I’m trying to merge my player’s dodging state into my main RPG Core Combat Creator code, but I’m running into some funny issues, and I have no idea why. So, here’s my plan for this:

Split the Dodging state into two different aspects:

  1. The Dodging in ‘PlayerFreeLookState’. Essentially, this one will be a simple animation, which is responsible for dodging when the player is freely roaming in the game. This one is meant to be a little more relaxing, and just something to use when you’re not in Combat. It could be for puzzles and other things…

  2. The Dodging in ‘PlayerTargetingState’. This one is for the intense fights, and will include a full blend tree with about double the speed of the regular one, for the times when you actually need to evade a big hit or equivalent

The reason I’m splitting it up into two parts, is because it’s easier for me to read down the line

Anyway, currently I’m still working on developing the Free Look Dodging State, and here’s my script so far:

using RPG.States.Player;
using UnityEngine;

public class PlayerDodgingState : PlayerBaseState
{
    private readonly int DodgeRollHash = Animator.StringToHash("DodgeRoll");
    private readonly int FreeLookDodgeSpeedHash = Animator.StringToHash("FreeLookDodgeSpeed");

    private Vector3 dodgingDirectionInput;
    private float remainingDodgeTime;
    private float dodgeDuration;

    public PlayerDodgingState(PlayerStateMachine stateMachine, Vector3 dodgingDirectionInput) : base(stateMachine)
    {
        this.dodgingDirectionInput = dodgingDirectionInput.normalized;
    }

    public override void Enter()
    {
        Debug.Log($"Player Dodging State entered. Direction input is: {dodgingDirectionInput}");
        dodgeDuration = GetDodgeAnimationLength();
        remainingDodgeTime = dodgeDuration;

        stateMachine.Animator.CrossFadeInFixedTime(DodgeRollHash, stateMachine.CrossFadeDuration);

        // stateMachine.Health.SetInvulnerable(false);
    }

    public override void Tick(float deltaTime)
    {
        if (remainingDodgeTime > 0)
        {
            Vector3 movement = CalculateMovement(deltaTime);
            Move(movement * stateMachine.FreeLookDodgingSpeed, deltaTime);
            stateMachine.Animator.SetFloat(FreeLookDodgeSpeedHash, movement.magnitude, AnimatorDampTime, deltaTime);
            
            remainingDodgeTime -= deltaTime;

            if (remainingDodgeTime <= 0f)
            {
                stateMachine.SwitchState(new PlayerFreeLookState(stateMachine));
            }
        }
    }

    public override void Exit()
    {
        // stateMachine.Health.SetInvulnerable(false);
    }

    /// <summary>
    /// Accumulate the total length of the Dodge animation you're playing,
    /// to keep the transitions natural
    /// </summary>
    /// <returns></returns>
    private float GetDodgeAnimationLength() 
    {
        AnimatorClipInfo[] clipInfos = stateMachine.Animator.GetCurrentAnimatorClipInfo(0);
        foreach (var info in clipInfos) 
        {
            if (info.clip.name.Contains("Dodge")) 
            {
                return info.clip.length;
            }
        }
        return 1f; // if you can't find a 'Dodge' animation, return a value of 1
    }

    private Vector3 CalculateMovement(float deltaTime) 
    {
        Vector3 movement = new Vector3();
        movement += stateMachine.transform.right * dodgingDirectionInput.x * stateMachine.DodgeLength / GetDodgeAnimationLength();
        movement += stateMachine.transform.forward * dodgingDirectionInput.y * stateMachine.DodgeLength / GetDodgeAnimationLength();
        Debug.Log($"Movement * deltaTime value is: {movement * deltaTime}");
        return movement * deltaTime;
    }
}

My problem here is, the animation plays in place and he doesn’t physically move ahead when the animation plays, and I’m really confused as to why

This may also may or may not be important, but the animation I’m using is Non-Root Motion by default nature (I couldn’t find something static to work with)

Does anyone have any idea why this is the case?


And something else before I forget, what are the negative impacts of mixing Unity’s new Input System with the old ‘Input.GetKeyDown(KeyCode.(some button here));’? I just find that with specific keys, the new input system simply isn’t responsive 100% of the time, and it’s been bothering me for a while now (stuff like Running, Sprint-Swimming and Diving that require the Shift Key, and Dodging that demands the Control Key… all these buttons do not have a 100% response rate for some reason (i.e: They have some serious delays). For the time being, I’m using an awkward set of buttons that simply can never make it out in the final product, just for testing purposes)

Ahh, nevermind… my ‘CalculateMovement()’ function was a complete mess, so I went and copied a little bit of my homework from ‘PlayerSwimmingState.cs’ (P.S: This is something I solely created. It’s not part of any course or YouTube video, just my creation for my game xD), and that seemed to solve the problem

and then I created a Quaternion-based ‘FaceMovementDirection()’ function, to ensure that we’re always looking the right way when dodging

And… I removed any sort of invulnerabilities whilst dodging. If you got hit whilst dodging, you got hit whilst dodging. It’s not a shield movement :stuck_out_tongue:

Time to give the Targeting State’s Dodging State Variant a try (which, I’m guessing will be significantly harder than the FreeLook one)

I still have a question (again) though, why are we normalizing the forward and right movement values again…?! I keep forgetting why we’re doing this part


Edit 1: New problem… you can dodge your way through the water’s targeter, and end up walking underwater

That’s just my code dodging me as well I suppose… sigh

Anyway, I introduced an ‘isDivingOrUnderwater’ boolean in ‘PlayerStateMachine.cs’, with a getter and setter, which gets activated and deactivated in my game when water is detected, and based on that, in ‘PlayerFreeLookDodgingState.cs’ (like I said, I split dodging to 2 parts, Part 1 of free look is complete), if this boolean is activated, we switch to ‘PlayerSwimmingState.cs’ and quits the dodging state.

This ensures he doesn’t dodge his way to the bottom of the ocean on foot

I don’t know how to say this… but you’re starting to sound like a problem solver. Well done!

1 Like

Thank you! One of my family members was quietly betting on this, that one day you’ll admit that I’m starting to solve my own problems :stuck_out_tongue_winking_eye: - I guess they won the bet now. The rules of the game, is I wasn’t supposed to tell you about this, xD (Just so you know, I’ll still need your help)

I’m just trying to rely a little more on myself whenever I can, but it’s taking me some time to figure all this stuff out bit by bit (and a lot of isolation…). For now, my best bet is to recycle stuff we’ve done before. In other words, if I can find something similar to my problem done before, I can do my best to tweak it and make it work for whatever problem we have (albeit sometimes I cheat… I have a funky looking solution that includes an ‘Update()’ (with a boolean flag that ends with a return, so there’s not much of performance issues here) function in my ‘AggroGroup.cs’ script, which I did for my AI Fighting System to shut down any aggression for the killer beyond the death of the victim)

And then I worked on my entire dodging targeting state. This one had quite a few modifications (because you can’t ‘FaceMovementDirection()’ this one, you’ll need the input of the X and Y-axis values to use in the blend tree), but it works. Albeit there’s a bit of a visual problem when you’re holding two keys down (i.e: Midway through the dodge, it gets a little confused on where should it face, because it’s being held down by 2 buttons), but we should be just fine

By the way, all the best tomorrow. You’ll be fine :laughing:

This is done by developers a LOT.

I mean… “If it works, don’t touch it”, right? :laughing:

By the way, this is where I’m currently stuck

Privacy & Terms