using UnityEngine; using Saltosion.OneWeapon.Player; using Saltosion.OneWeapon.Enemies; namespace Saltosion.OneWeapon.AI.Behaviours { [RequireComponent(typeof(Follow), typeof(Enemy))] public class MeleeAttackFollowed : AIBehaviour { [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 Enemy Enemy; private Follow Follow; private bool AttackHit; private float AnimationProgress; private float CooldownProgress; private Vector3 LocalOrigin; private void Start() { Enemy = GetComponent(); Follow = GetComponent(); 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() { bool CanBehave = Follow.Target != null && (Follow.Target.position - Enemy.transform.position).magnitude <= MeleeRange; if (!CanBehave) { Enemy.Attacking = false; } return CanBehave; } public override void Execute() { if (CooldownProgress > 0) { Enemy.Attacking = false; return; } else { Enemy.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 TakeFunDamage(); 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(); } } } private void TakeFunDamage() { PlayerFun Player = Follow.Target.GetComponent(); if (Player != null) { Player.TakeDamage(); } } private void OnDrawGizmosSelected() { Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, MeleeRange); } } }