Files

196 lines
3.8 KiB
C#

using UnityEngine;
public class Enemy : MonoBehaviour, IMovementDirection
{
[Header("Movement")]
[SerializeField]
private float moveSpeed = 0.5f;
[SerializeField]
private float targetReachedDistance = 0.1f;
private EnemyTargetManager targetManager;
private Transform currentTarget;
// Wird von CharacterRotation verwendet.
public Vector2 MovementDirection { get; private set; }
[Header("Health")]
[SerializeField]
private float maxHealth = 100f;
private float currentHealth;
public float CurrentHealth => currentHealth;
public bool IsDead { get; private set; }
private void Awake()
{
currentHealth = maxHealth;
targetManager =
FindFirstObjectByType<EnemyTargetManager>();
if (targetManager == null)
{
Debug.LogError(
"Enemy: Kein EnemyTargetManager gefunden!",
this
);
}
}
private void OnEnable()
{
if (targetManager != null)
{
targetManager.OnTargetsChanged +=
SelectClosestTarget;
}
}
private void OnDisable()
{
if (targetManager != null)
{
targetManager.OnTargetsChanged -=
SelectClosestTarget;
}
}
private void Start()
{
if (targetManager == null)
return;
SelectClosestTarget();
}
private void Update()
{
if (targetManager == null)
return;
// Kein aktuelles Ziel vorhanden.
if (currentTarget == null)
{
MovementDirection = Vector2.zero;
SelectClosestTarget();
return;
}
// Das aktuelle Ziel wurde deaktiviert.
if (!currentTarget.gameObject.activeInHierarchy)
{
SelectClosestTarget();
return;
}
MoveTowardsTarget();
// Ziel erreicht.
if (HasReachedTarget())
{
SelectClosestTarget();
}
}
// BEWEGUNGSLOGIK
//
private void SelectClosestTarget()
{
if (targetManager == null)
return;
currentTarget =
targetManager.GetClosestActiveTarget(
transform.position
);
if (currentTarget == null)
{
MovementDirection = Vector2.zero;
}
}
private void MoveTowardsTarget()
{
if (currentTarget == null)
return;
Vector3 direction =
currentTarget.position - transform.position;
MovementDirection = new Vector2(
direction.x,
direction.y
).normalized;
transform.position = Vector3.MoveTowards(
transform.position,
currentTarget.position,
moveSpeed * Time.deltaTime
);
}
private bool HasReachedTarget()
{
if (currentTarget == null)
return false;
return Vector3.Distance(
transform.position,
currentTarget.position
) <= targetReachedDistance;
}
// LEBENSLOGIK
//
public void TakeDamage(float damage)
{
if (IsDead || damage <= 0f)
return;
currentHealth -= damage;
Debug.Log(
gameObject.name +
" erhält " + damage +
" Schaden. HP: " +
currentHealth + "/" + maxHealth
);
if (currentHealth <= 0f)
{
Die();
}
}
private void Die()
{
if (IsDead)
return;
IsDead = true;
Debug.Log(
gameObject.name + " wurde besiegt!"
);
Destroy(gameObject);
}
// ANGRIFFSLOGIK (möglicherweise in anderem Skript)
//
}