I’ve a few lectures ahead where ai follow and attacking is introduced, and there is a bug when it comes to the very first attack/punch. For both the player and AI there Is a delay.
It seems to happen when first getting the target after moving, if I click to attack multiple enemies in range and change between them the attack speed works correctly.
But whenever I move and then click on an enemy again the initial delay bug happens.
[RequireComponent(typeof(ActionScheduler))]
public class Fighter : MonoBehaviour, IAction
{
[SerializeField] Health _targetHealth;
[SerializeField] float _weaponRange = 2f;
[SerializeField] float _timeBetweenAttacks = 1f;
[SerializeField] float _weaponDamage = 5f;
Animator _animator;
Mover _mover;
float _timeSinceLastAttack = 0;
private void Awake()
{
_mover = GetComponent<Mover>();
_animator = GetComponent<Animator>();
}
void Update()
{
if (_targetHealth == null || _targetHealth.IsDead) return;
_timeSinceLastAttack += Time.deltaTime;
if (IfNotInWeaponRange())
{
_mover.MoveTo(_targetHealth.transform.position);
}
else
{
_mover.CancelAction();
AttackBehaviour();
}
}
void AttackBehaviour()
{
transform.LookAt(_targetHealth.transform.position);
if (_timeSinceLastAttack >= _timeBetweenAttacks)
{
TriggerAttack();
_timeSinceLastAttack = 0;
}
}
void TriggerAttack()
{
_animator.ResetTrigger("StopAttack");
_animator.SetTrigger("AttackState");
}
//Animation event called on hit part of attack animation
void Hit()
{
if (_targetHealth == null){ return; }
_targetHealth.TakeDamage(_weaponDamage);
}
public bool IfNotInWeaponRange()
{
return Vector3.Distance(transform.position, _targetHealth.transform.position) >= _weaponRange;
}
public void Attack(GameObject combatTarget)
{
GetComponent<ActionScheduler>().StartAction(this);
_targetHealth = combatTarget.GetComponent<Health>();
}
public void CancelAction()
{
_targetHealth = null;
StopAttack();
}
private void StopAttack()
{
_animator.SetTrigger("StopAttack");
_animator.ResetTrigger("AttackState");
}
public bool CanAttack(GameObject combatTarget)
{
if (combatTarget == null){ return false; }
Health targetToTest = combatTarget.GetComponent<Health>();
return targetToTest != null && targetToTest.IsDead == false;
}
}