213 lines
5.1 KiB
C#
213 lines
5.1 KiB
C#
using Cinemachine;
|
|
using System;
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
|
|
public class Health : MonoBehaviour
|
|
{
|
|
public float currentHealth;
|
|
public float maxHealth = 100f;
|
|
|
|
// Event used by UI or other systems to react to health changes
|
|
public event Action<float, float> OnHealthChanged;
|
|
|
|
private CharacterController controller;
|
|
public bool isHit;
|
|
public bool isDead;
|
|
|
|
[SerializeField] private float knockbackForce = 4f;
|
|
[SerializeField] private float knockbackDuration = 0.2f;
|
|
|
|
private Vector3 knockbackVelocity;
|
|
private float knockbackTimer;
|
|
|
|
private NavMeshAgent agent;
|
|
|
|
//[SerializeField] private float knockbackForce = 6f;
|
|
//[SerializeField] private float knockbackDuration = 0.2f;
|
|
//private Vector3 knockbackVelocity;
|
|
//private float knockbackTimer;
|
|
|
|
void Awake()
|
|
{
|
|
controller = GetComponent<CharacterController>();
|
|
agent = GetComponent<NavMeshAgent>();
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
currentHealth = maxHealth;
|
|
|
|
OnHealthChanged?.Invoke(currentHealth, maxHealth);
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (isDead) return;
|
|
|
|
if (knockbackTimer > 0)
|
|
{
|
|
knockbackTimer -= Time.deltaTime;
|
|
|
|
// ONLY move via CharacterController if it is still enabled
|
|
if (controller != null && controller.enabled)
|
|
{
|
|
controller.Move(knockbackVelocity * Time.deltaTime);
|
|
}
|
|
|
|
// TEMP stop agent movement only if agent is enabled and active
|
|
if (agent != null && agent.enabled && agent.isOnNavMesh)
|
|
{
|
|
agent.isStopped = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Resume AI movement only if agent is enabled and active
|
|
if (agent != null && agent.enabled && agent.isOnNavMesh)
|
|
{
|
|
agent.isStopped = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void TakeDamage(float amount, string bodyPart)
|
|
{
|
|
if (isDead) return;
|
|
|
|
currentHealth = Mathf.Clamp(currentHealth - amount, 0, maxHealth);
|
|
OnHealthChanged?.Invoke(currentHealth, maxHealth);
|
|
|
|
// PLAY ENEMY GRUNT SOUND
|
|
if (AudioManager.Instance != null)
|
|
{
|
|
AudioManager.Instance.PlayEnemyHit();
|
|
}
|
|
|
|
PlayerControllerNewRohan player = GetComponent<PlayerControllerNewRohan>();
|
|
|
|
if (player != null)
|
|
{
|
|
player.CancelAttack();
|
|
}
|
|
|
|
//SimpleEnemyAI enemy = GetComponent<SimpleEnemyAI>();
|
|
|
|
//if (enemy != null)
|
|
//{
|
|
// enemy.CancelAttackAndHit(bodyPart);
|
|
//}
|
|
|
|
var receiver = GetComponent<IDamageReceiver>();
|
|
receiver?.OnDamageTaken(bodyPart);
|
|
|
|
// DEATH CHECK
|
|
if (currentHealth <= 0)
|
|
{
|
|
Die();
|
|
}
|
|
}
|
|
|
|
void Die()
|
|
{
|
|
if (isDead) return;
|
|
|
|
isDead = true;
|
|
|
|
DisableAfterDeath();
|
|
|
|
CashManager cashManager = GetComponent<CashManager>();
|
|
|
|
if (cashManager != null)
|
|
{
|
|
cashManager.DropAllCash();
|
|
}
|
|
|
|
Animator anim = GetComponent<Animator>();
|
|
|
|
if (anim != null)
|
|
{
|
|
anim.SetTrigger("Death");
|
|
}
|
|
|
|
// STOP NAVMESH
|
|
// STOP NAVMESH
|
|
if (agent != null && agent.enabled)
|
|
{
|
|
if (agent.isOnNavMesh)
|
|
{
|
|
agent.isStopped = true;
|
|
agent.ResetPath();
|
|
agent.velocity = Vector3.zero;
|
|
}
|
|
|
|
agent.enabled = false;
|
|
}
|
|
|
|
// DISABLE PLAYER CONTROLLER
|
|
PlayerControllerNewRohan player = GetComponent<PlayerControllerNewRohan>();
|
|
|
|
if (player != null)
|
|
{
|
|
player.enabled = false;
|
|
}
|
|
|
|
// DISABLE ENEMY AI
|
|
//SimpleEnemyAI enemy = GetComponent<SimpleEnemyAI>();
|
|
|
|
//if (enemy != null)
|
|
//{
|
|
// enemy.enabled = false;
|
|
//}
|
|
|
|
// OPTIONAL
|
|
CharacterController cc = GetComponent<CharacterController>();
|
|
|
|
if (cc != null)
|
|
{
|
|
cc.enabled = false;
|
|
}
|
|
|
|
// Destroy after animation
|
|
Destroy(gameObject, 2f);
|
|
}
|
|
|
|
public void ApplyKnockback(Vector3 direction, float forceMultiplier = 1f)
|
|
{
|
|
if (knockbackTimer > 0) return; // prevent stacking
|
|
|
|
direction.Normalize();
|
|
|
|
// Add slight upward push (optional but feels better)
|
|
Vector3 finalDir = direction;
|
|
|
|
knockbackVelocity = finalDir * knockbackForce * forceMultiplier;
|
|
knockbackTimer = knockbackDuration;
|
|
}
|
|
|
|
void DisableAfterDeath()
|
|
{
|
|
gameObject.tag = "Untagged";
|
|
|
|
Collider[] colliders = GetComponentsInChildren<Collider>();
|
|
|
|
foreach (Collider col in colliders)
|
|
{
|
|
col.enabled = false;
|
|
}
|
|
|
|
SimpleTeamAI ai = GetComponent<SimpleTeamAI>();
|
|
|
|
if (ai != null)
|
|
ai.enabled = false;
|
|
|
|
MonoBehaviour[] scripts = GetComponentsInChildren<MonoBehaviour>();
|
|
|
|
foreach (MonoBehaviour script in scripts)
|
|
{
|
|
if (script != this && script.GetType() != typeof(Animator))
|
|
script.enabled = false;
|
|
}
|
|
}
|
|
} |