using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Saltosion.OneWeapon.AI.Behaviours { public class MeleeAttackFollowed : AIBehaviour { public Follow Follow; [Tooltip("This should be at 0,0,0 locally by default.")] public Transform AnimatableTransform; public float MeleeRange; public float AttackAnimationLength; public float ReleaseAnimationLength; public float CooldownLength; private bool AttackHit; private float AnimationProgress; private float CooldownProgress; private Vector3 LocalOrigin; private void Start() { if (AnimatableTransform.localPosition.magnitude != 0) { Debug.LogWarning($"{name} has an animated melee attack, and AnimatableTransform is not at local origin!"); } LocalOrigin = AnimatableTransform.localPosition; Reset(); } private void Reset() { AttackHit = false; AnimationProgress = 0.0f; CooldownProgress = 1.0f; AnimatableTransform.localPosition = LocalOrigin; } private void Update() { if (CooldownProgress > 0) { CurrentStatus = "Cooldown"; CooldownProgress -= Time.deltaTime / CooldownLength; } } public override bool CanBehave(Enemy subject) { bool CanBehave = Follow.Target != null && (Follow.Target.position - subject.transform.position).magnitude <= MeleeRange; if (!CanBehave) { subject.Attacking = false; } return CanBehave; } public override bool Execute(Enemy subject) { if (CooldownProgress > 0) { subject.Attacking = false; return false; } else { subject.Attacking = true; } Vector2 Root = AnimatableTransform.parent.position + LocalOrigin; Vector2 Target = Follow.Target.transform.position; if (!AttackHit) { CurrentStatus = "Hit"; AnimationProgress += Time.deltaTime / AttackAnimationLength; AnimatableTransform.position = Vector2.Lerp(Root, Target, AnimationProgress); if (AnimationProgress >= 1.0f) { // Attack hit, deal damage and start return animation AttackHit = true; AnimationProgress = 0.0f; } } else { CurrentStatus = "Retreat"; AnimationProgress += Time.deltaTime / ReleaseAnimationLength; AnimatableTransform.position = Vector2.Lerp(Target, Root, AnimationProgress); if (AnimationProgress >= 1.0f) { // Attack finished, reset Reset(); } } return false; } private void OnDrawGizmosSelected() { Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, MeleeRange); } } }