Animation bug

When I click the attack button is it supposed to fully play the first attack animation? At the moment it stutters and plays the first few frames of the animation and then returns. It only fully plays when I hold down the attack input.

public class PlayerAttackingState : PlayerBaseState
{
    private float previousFrameTime;
    private bool alreadyAppliedForce;
    
    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();

        if (normalizedTime >= previousFrameTime && normalizedTime < 1f)
        {
            if (normalizedTime >= attack.ForceTime)
            {
                TryApplyForce();
            }
            
            if (stateMachine.InputReader.isAttacking)
            {
                TryComboAttack(normalizedTime);
            }
            else
            {
                if (stateMachine.Targeter.CurrentTarget != null)
                {
                   stateMachine.SwitchState(new PlayerTargetingState(stateMachine)); 
                }
                else
                {
                    stateMachine.SwitchState(new PlayerFreeLookState(stateMachine));
                }
            }
        }

        previousFrameTime = normalizedTime;
    }

    public override void Exit()
    {
        
    }

    private void TryComboAttack(float normalizedTime)
    {
       if(attack.ComboStateIndex == -1)  {return;}
       
       if(normalizedTime < attack.ComboAttackTime) {return;}
       
       stateMachine.SwitchState
           (
               new PlayerAttackingState(stateMachine, attack.ComboStateIndex)
           );
    }

This is an easy mistake to make, as it applies to what if statement the else clause is referring to. In the code you’ve pasted, the else clause is attached to the if(stateMachine.InputReader.isAttacking), which means that if the button is no longer held, it will fall out of the state.

Here’s the method from the course repo. Note the arrangement of the brackets. The two if statements after the first one are encapsulated within a set of brackets, so that the else is responding to the first condition and not the stateMachine.InputReader condition.

    public override void Tick(float deltaTime)
    {
        Move(deltaTime);

        FaceTarget();

        float normalizedTime = GetNormalizedTime(stateMachine.Animator, "Attack");

        if (normalizedTime >= previousFrameTime && normalizedTime < 1f)
        {
            if (normalizedTime >= attack.ForceTime)
            {
                TryApplyForce();
            }

            if (stateMachine.InputReader.IsAttacking)
            {
                TryComboAttack(normalizedTime);
            }
        }
        else
        {
            if (stateMachine.Targeter.CurrentTarget != null)
            {
                stateMachine.SwitchState(new PlayerTargetingState(stateMachine));
            }
            else
            {
                stateMachine.SwitchState(new PlayerFreeLookState(stateMachine));
            }
        }

        previousFrameTime = normalizedTime;
    }
1 Like

Thanks!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms