BloodAndGore/Assets/Scripts/AI/Behaviours/MeleeAttackFollowed.cs

102 lines
3.5 KiB
C#

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;
[HideInInspector]
public bool Attacking;
private Enemy Enemy;
private Follow Follow;
private bool AttackHit;
private float AnimationProgress;
private float CooldownProgress;
private Vector3 LocalOrigin;
private void Start() {
Enemy = GetComponent<Enemy>();
Follow = GetComponent<Follow>();
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) {
Attacking = false;
}
return CanBehave;
}
public override void Execute() {
if (CooldownProgress > 0) {
Attacking = false;
return;
} else {
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<PlayerFun>();
if (Player != null) {
Player.TakeDamage();
}
}
private void OnDrawGizmosSelected() {
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, MeleeRange);
}
}
}