Bug still present

I have the same code as in the lecture, but I still get the code wherein the stopAttack trigger isnt getting reset. What seems to be amiss?

My code:

Fighter.cs

using RPG.Movement;
using UnityEngine;
using RPG.Core;

namespace RPG.Combat
{
    public class Fighter : MonoBehaviour, IAction
    {
        [SerializeField] float weaponRange = 2f;
        [SerializeField] float timeBetweenAttacks = 1f;
        [SerializeField] int minWeaponDamage = 3;
        [SerializeField] int maxWeaponDamage = 15;

        Health target;
        int weaponDamage;
        float timeSinceLastAttack = 0f;

        private void Update()
        {
            timeSinceLastAttack += Time.deltaTime;

            if(target == null) return;
            if(target.IsDead()) return;

            if (!GetIsInRange())
            {
                GetComponent<Mover>().MoveTo(target.transform.position);
            }
            else
            {
                GetComponent<Mover>().Cancel();
                AttackBehaviour();
            }

            weaponDamage = Random.Range(minWeaponDamage, maxWeaponDamage);
        }

        private void AttackBehaviour()
        {
            transform.LookAt(target.transform);
            if(timeSinceLastAttack > timeBetweenAttacks)
            {
                //This will trigger the Hit event
                TriggerAttack();
                timeSinceLastAttack = 0;
            }
        }

        private void TriggerAttack()
        {
            GetComponent<Animator>().SetTrigger("attack");
            GetComponent<Animator>().ResetTrigger("stopAttack");
        }

        //This is an animation event
        void Hit()
        {
            if(target == null) return;
            target.TakeDamage(weaponDamage);
        }

        private bool GetIsInRange()
        {
            return Vector3.Distance(transform.position, target.transform.position) < weaponRange;
        }

        public bool CanAttack(CombatTarget combatTarget)
        {
            if(combatTarget == null) return false;

            Health targetToTest = combatTarget.GetComponent<Health>();
            return targetToTest != null && !targetToTest.IsDead();
        }

        public void Attack(CombatTarget combatTarget)
        {
            GetComponent<ActionScheduler>().StartAction(this);
            target = combatTarget.GetComponent<Health>();
        }

        public void Cancel()
        {
            StopAttack();
            target = null;
        }

        private void StopAttack()
        {
            GetComponent<Animator>().SetTrigger("stopAttack");
            GetComponent<Animator>().ResetTrigger("attack");
        }
    }
}

Try reversing the order of operations in TriggerAttack and StopAttack

private void TriggerAttack()
{
    GetComponent<Animator>().ResetTrigger("stopAttack");
    GetComponent<Animator>().SetTrigger("attack);
}

private void StopAttack()
{
    GetComponent<Animator>().ResetTrigger("attack");
    GetComponent<Animator>().SetTrigger("stopAttack");
}

This ensures that the triggers are reset before the opposite trigger is set. When we call the trigger before resetting the opposite trigger, the Animator immediately checks the state and acts on the trigger, but also acts on the stopAttack trigger if it’s still set, dropping us right back into locomotion. By resetting it before calling attack, this means it should only fire the attack, and never the stopAttack unless it’s called by stopAttack.

I reversed the order of operations and it still didnt do anything unfortunately. I can see that after attacking, when i move away and try attacking again immediately, the stopAttack trigger doesnt reset, despite logic dictating that it should. Not sure if I have something wrong set up in the Animator.

That is odd…
Brute force it is, then:

void TriggerAttack()
{
    GetComponent<Animator>().ResetTrigger("attack");
    GetComponent<Animator>().ResetTrigger("stopAttack);
    GetComponent<Animator>().SetTrigger("attack");
}

void StopAttack()
{
    GetComponent<Animator>().ResetTrigger("attack");
    GetComponent<Animator>().ResetTrigger("stopAttack");
    GetComponent<Animator>().SetTrigger("stopAttack");
}

Hmm, that didnt work either. I have a recording of my screen showing the issue at hand

This behavior actually looks correct…
The attack is so quick, that you’re actually clicking away after the attack has already finished (in order to make animation look smooth, the transition actually happens a bit before it looks like it does). In this case, the enemy is still alive, so we’re cancelling and setting the trigger. It’s hanging out as left set, but this isn’t a problem, because stopAttack is only needed when we are in an attack state, which we aren’t. When you attack another character, as soon as the attack is triggered the stop is properly cancelled.

I see, that makes sense. In the lecture it looked as if the stopTrigger was reset when Rick attacked again after cancelling, and since I did not have that behavior in my code, I assumed that I still had the bug. But this isnt a game breaking bug and it might not be good to focus too much on this to begin with. I can mark it down to investigate later on, but I believe your explanation makes sense. Thanks a lot!

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