Combo not working

Hi, i was following the lesson and everything seemed ok but when i pressed play the combo was not working.
I have changed the parameters in the inspector for the attacks and i even tried to mess with the parameters a bit but the results weren’t the expected ones.
I managed only to get a super quick combo, witch was cutting almost all of my animations and ended up waving the sword in the air like the player was drunk.
I run some tests and i found out that my function GetNormalizedTime() always returns the nextinfo.normalizedTime and never the currentinfo.normalizedTime.
I think that the problem may be with the statemachine.animator.IsInTransition(0) because it’s the only parameter that changes in the if statement of the function.
The description of IsInTransition() says that the value is going to be true if there is a transition on the specified animator layer.
Maybe the freelook and targeting blend trees are messing with this value?
I tried to fix it but my solution ended up being to different from the course files and i’m afraid that i won’t be able to continue to follow the course properly having such different code.
I will attach my PlayerAttackingState script down below for you to check it out.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAttackingState : PlayerBaseState
{
    private float previousFrameTime;
    private Attack attack;
    public PlayerAttackingState(PlayerStateMachine stateMachine, int AttackIndex) : base(stateMachine)
    {
        attack = stateMachine.Attacks[AttackIndex];
    }

    public override void Enter()
    {
        stateMachine.animator.CrossFadeInFixedTime(attack.AnimationName, attack.TransitionDuration);
    }

    public override void Tick(float deltaTime)
    {
        Move(deltaTime);
        Facetarget();
        float normalizedTime = GetNormalizedTime();
        Debug.Log("normalizedTime: " + normalizedTime);
        Debug.Log("previousFrameTime: " + previousFrameTime);
        if (normalizedTime > previousFrameTime && normalizedTime < 1f)
        {
            if (stateMachine.inputReader.IsAttacking)
            {
                TryComboAttack(normalizedTime);
            }
        }
        previousFrameTime = normalizedTime;
    }

    public override void Exit()
    {
        
    }

    private void TryComboAttack(float normalizedTime)
    {
        if(attack.ComboStateIndex == -1f) { Debug.Log("No combo"); return; }
        if(normalizedTime < attack.ComboAttackTime) { Debug.Log("Too early"); return; }
        Debug.Log("Switching state!");
        stateMachine.SwitchState(new PlayerAttackingState(stateMachine,attack.ComboStateIndex));
    }

    private float GetNormalizedTime()
    {
        AnimatorStateInfo currentinfo = stateMachine.animator.GetCurrentAnimatorStateInfo(0);
        AnimatorStateInfo nextinfo = stateMachine.animator.GetNextAnimatorStateInfo(0);
        if(stateMachine.animator.IsInTransition(0) && nextinfo.IsTag("Attack"))
        {
            Debug.Log("Getting the next normalized time");
            return nextinfo.normalizedTime;
        }
        else if (!stateMachine.animator.IsInTransition(0) && nextinfo.IsTag("Attack"))
        {
            Debug.Log("Getting the current normalized time");
            return currentinfo.normalizedTime;
        }
        else
        {
            return 0f;
        }
    }
}

I can’t find any meaningful differences between this script and the one Nathan uses in the course.

It’s not clear in your question… is the combo working now, or is it still firing almost immediately?

It’s firing immediately, witch is not the effect i want to achieve.
The only different thing from Nathan’s setup is the animation pack.
I used a katana sword animation set, the attack animations are pretty fast but not as fast as the script makes them run.
I tried also by slowing the animations down but it still produces the same issue.
Should i try to make my own implementation of the combo system?
Or it’s better that i fix this issue to continue to follow along with the course?
I tried al sorts of fixes i could think of ( i’m still not experienced enough to say that i’ve tried it all ) but still i can’t fix the issue without touching the code.
Btw thanks for taking my problem into consideration.

Nevermind i managed to fix it!
As i supposed the issue was with the “animator.IsInTransition(0)”, idk why but the value was always true for me.
So i implemented a check with uses the attack.ComboAttackTime to check for the correct normalizedTime to use.
I’m attaching the modified script down below for you to check it out.
I’m very happy i was able to solve this issue by myself, now it’s time to optimize my solution and then the code will be ok to proceed to the next lecture.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAttackingState : PlayerBaseState
{
    private float previousFrameTime;
    private Attack attack;
    public PlayerAttackingState(PlayerStateMachine stateMachine, int AttackIndex) : base(stateMachine)
    {
        attack = stateMachine.Attacks[AttackIndex];
    }

    public override void Enter()
    {
        stateMachine.animator.CrossFadeInFixedTime(attack.AnimationName, attack.TransitionDuration);
    }

    public override void Tick(float deltaTime)
    {
        Move(deltaTime);
        Facetarget();
        float normalizedTime = GetNormalizedTime();
        Debug.Log("normalizedTime: " + normalizedTime);
        Debug.Log("previousFrameTime: " + previousFrameTime);
        if (normalizedTime > previousFrameTime && normalizedTime < 1f)
        {
            if (stateMachine.inputReader.IsAttacking)
            {
                TryComboAttack(normalizedTime);
            }
        }
        previousFrameTime = normalizedTime;
    }


    public override void Exit()
    {
        
    }

    private void TryComboAttack(float normalizedTime)
    {
        if(attack.ComboStateIndex == -1f) { Debug.Log("No combo"); return; }
        if(normalizedTime < attack.ComboAttackTime) { Debug.Log("Too early"); return; }
        Debug.Log("Switching state!");
        stateMachine.SwitchState(new PlayerAttackingState(stateMachine,attack.ComboStateIndex));
    }
    private float GetNormalizedTime()
    {
        AnimatorStateInfo currentinfo = stateMachine.animator.GetCurrentAnimatorStateInfo(0);
        AnimatorStateInfo nextinfo = stateMachine.animator.GetNextAnimatorStateInfo(0);
        if (currentinfo.IsTag("Attack"))
        {
            if (nextinfo.IsTag("Attack") && currentinfo.normalizedTime > attack.ComboAttackTime)
            {
                return nextinfo.normalizedTime;
            }
            else
            {
                return currentinfo.normalizedTime;

            }
        }
        else
        {
            return 0f;
        }
    }

I’m glad to see that’s working for you. I’m not entirely sure why the IsInTransition() wasnt’ working for you.

One of the things about using Normalized time is you don’t have to worry about the actual length of the animation, only what percentage of the animation is completed. This should make timing much easier to implement.

Privacy & Terms