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

102 lines
3.5 KiB
C#
Raw Normal View History

using UnityEngine;
2019-08-14 16:17:48 +02:00
using Saltosion.OneWeapon.Player;
using Saltosion.OneWeapon.Enemies;
2019-08-04 17:35:24 +02:00
namespace Saltosion.OneWeapon.AI.Behaviours {
2019-08-14 18:05:41 +02:00
[RequireComponent(typeof(Follow), typeof(Enemy))]
2019-08-04 17:35:24 +02:00
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;
2019-08-14 21:31:58 +02:00
[HideInInspector]
public bool Attacking;
2019-08-14 18:05:41 +02:00
private Enemy Enemy;
private Follow Follow;
2019-08-04 17:35:24 +02:00
private bool AttackHit;
private float AnimationProgress;
private float CooldownProgress;
private Vector3 LocalOrigin;
private void Start() {
2019-08-14 18:05:41 +02:00
Enemy = GetComponent<Enemy>();
Follow = GetComponent<Follow>();
2019-08-04 17:35:24 +02:00
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;
}
}
2019-08-14 18:05:41 +02:00
public override bool CanBehave() {
bool CanBehave = Follow.Target != null && (Follow.Target.position - Enemy.transform.position).magnitude <= MeleeRange;
2019-08-04 20:09:00 +02:00
if (!CanBehave) {
2019-08-14 21:31:58 +02:00
Attacking = false;
2019-08-04 20:09:00 +02:00
}
return CanBehave;
2019-08-04 17:35:24 +02:00
}
2019-08-14 18:05:41 +02:00
public override void Execute() {
2019-08-04 17:35:24 +02:00
if (CooldownProgress > 0) {
2019-08-14 21:31:58 +02:00
Attacking = false;
2019-08-14 18:05:41 +02:00
return;
2019-08-04 20:09:00 +02:00
} else {
2019-08-14 21:31:58 +02:00
Attacking = true;
2019-08-04 17:35:24 +02:00
}
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
2019-08-04 20:38:57 +02:00
TakeFunDamage();
2019-08-04 17:35:24 +02:00
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();
}
}
}
2019-08-04 20:38:57 +02:00
private void TakeFunDamage() {
PlayerFun Player = Follow.Target.GetComponent<PlayerFun>();
if (Player != null) {
Player.TakeDamage();
}
}
2019-08-04 17:35:24 +02:00
private void OnDrawGizmosSelected() {
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, MeleeRange);
}
}
}