Click to Attack (having trouble)

You are the absolute GOAT. This was everything I wanted regarding the sword swing part of my melee combat system. It feels responsive and flexible, especially when I time the ComboAttackTime (in the Inspector) to just past the DisableWeapon() function in the Animator Window. Thank you so much, I’ll be sure to give you credit for helping me make my game!

For anyone else reading, here is Bixarrio and I’s full PlayerAttackingState script. Feel free to copy and paste.

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

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

    public override void Enter()
    {
        stateMachine.InputReader.AttackDown += HandleAttackDown; //Enables Button Push
        
        stateMachine.Weapon.SetAttack(attack.Damage, attack.Knockback);
        stateMachine.Animator.CrossFadeInFixedTime(attack.AnimationName, attack.TransitionDuration);
        Debug.Log(attack.AnimationName);
    }

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

        float normalizedTime = GetNormalizedTime(stateMachine.Animator, "Attack");
            
        if(normalizedTime < 1f)
        {
            if (normalizedTime >= attack.ForceTime)
            {
                TryApplyForce();
            }
            
            /*if(stateMachine.InputReader.IsAttacking)
            {
                TryComboAttack(normalizedTime);
            } Enables Button Hold*/
        }
        else
        {
            if(stateMachine.Targeter.CurrentTarget != null)
            {
                stateMachine.SwitchState(new PlayerTargetingState(stateMachine));
            }
            else
            {
                stateMachine.SwitchState(new PlayerFreeLookState(stateMachine));
            }
        }
        
        previousFrameTime = normalizedTime;
    }
    public override void Exit()
    {
        stateMachine.InputReader.AttackDown -= HandleAttackDown; //Enables Button Push
    }
    private void TryComboAttack(float normalizedTime)
    {
        if(attack.ComboStateIndex == -1) { return; }

        if(normalizedTime < attack.ComboAttackTime) { return; }

        stateMachine.SwitchState
        (
            new PlayerAttackingState
            (
                stateMachine,
                attack.ComboStateIndex
            )
        );
    }
    private void TryApplyForce()
    {
        if(alreadyAppliedForce) { return; }
        stateMachine.ForceReceiver.AddForce(stateMachine.transform.forward * attack.Force);
        alreadyAppliedForce = true;
    }

    void HandleAttackDown()
    {
// stateMachine.InputReader.AttackDown -= HandleAttackDown; //Makes it harder to time combos.
        // with this enabled, you CANNOT button mash and expect to combo.

        float normalizedTime = GetNormalizedTime(stateMachine.Animator, "Attack");
        TryComboAttack(normalizedTime);
    }//Enables Button Push
}

This fragment of code was a leftover from the original prototype of the course. We didn’t realize until after the course was over that the previousFrameTime code is unimportant, as we’re already filtering for the previous frame in the GetNormalizedTime method.

1 Like

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

Privacy & Terms