132 lines
3.8 KiB
C#
132 lines
3.8 KiB
C#
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// Basic player combat controller: right-click an enemy to chase and attack in range.
|
|
/// </summary>
|
|
public class PlayerCombatController : MonoBehaviour
|
|
{
|
|
[Header("Combat")]
|
|
public int attackDamage = 1;
|
|
public float attackRange = 1.5f;
|
|
public float attackCooldown = 0.6f;
|
|
[Tooltip("Maximum chase distance. Clear target if enemy gets farther than this.")]
|
|
public float maxChaseDistance = 20f;
|
|
|
|
[Header("Movement")]
|
|
public bool useMovementController = true;
|
|
|
|
[Header("Debug")]
|
|
public bool enableDebugLogs = false;
|
|
|
|
private Enemy targetEnemy;
|
|
private float nextAttackTime = 0f;
|
|
private NavMeshMovementController movementController;
|
|
|
|
private void Awake()
|
|
{
|
|
movementController = GetComponent<NavMeshMovementController>();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (targetEnemy == null) return;
|
|
|
|
if (targetEnemy.GetCurrentHP() <= 0)
|
|
{
|
|
Log("Target enemy is dead, clearing combat target");
|
|
ClearCombatTarget();
|
|
return;
|
|
}
|
|
|
|
float distance = Vector3.Distance(transform.position, targetEnemy.transform.position);
|
|
|
|
// Auto-clear if enemy goes out of chase range
|
|
if (distance > maxChaseDistance)
|
|
{
|
|
Log($"Enemy out of chase range (distance: {distance:F2}, max: {maxChaseDistance:F2}), clearing target");
|
|
ClearCombatTarget();
|
|
return;
|
|
}
|
|
|
|
if (useMovementController && movementController != null)
|
|
{
|
|
if (distance > attackRange)
|
|
{
|
|
Log($"Moving to enemy (distance: {distance:F2} > attackRange: {attackRange})");
|
|
movementController.MoveTo(targetEnemy.transform.position);
|
|
}
|
|
else
|
|
{
|
|
Log($"In attack range, stopping (distance: {distance:F2})");
|
|
movementController.Stop();
|
|
movementController.SetLookTarget(targetEnemy.transform.position);
|
|
}
|
|
}
|
|
|
|
if (distance <= attackRange && Time.time >= nextAttackTime)
|
|
{
|
|
Log($"ATTACKING! Distance: {distance:F2}, Cooldown ready: {Time.time >= nextAttackTime}");
|
|
nextAttackTime = Time.time + attackCooldown;
|
|
|
|
Character character = GetComponent<Character>();
|
|
if (character != null)
|
|
{
|
|
character.TriggerAttack();
|
|
}
|
|
|
|
targetEnemy.TakeDamage(attackDamage);
|
|
}
|
|
}
|
|
|
|
public void SetTargetEnemy(Enemy enemy)
|
|
{
|
|
if (enemy == null) return;
|
|
|
|
Log($"Setting target: {enemy.enemyName}");
|
|
targetEnemy = enemy;
|
|
nextAttackTime = Time.time;
|
|
|
|
// Set weapon type to Melee for combat
|
|
Character character = GetComponent<Character>();
|
|
if (character != null)
|
|
{
|
|
character.SetWeaponType(Character.WeaponType.Melee);
|
|
}
|
|
}
|
|
|
|
public void ClearCombatTarget()
|
|
{
|
|
if (targetEnemy != null)
|
|
Log($"Clearing target: {targetEnemy.enemyName}");
|
|
targetEnemy = null;
|
|
|
|
// Return to idle weapon state
|
|
Character character = GetComponent<Character>();
|
|
if (character != null)
|
|
{
|
|
character.SetWeaponType(Character.WeaponType.None);
|
|
}
|
|
}
|
|
|
|
public Enemy GetTargetEnemy() => targetEnemy;
|
|
|
|
private void Log(string message)
|
|
{
|
|
if (enableDebugLogs)
|
|
{
|
|
Debug.Log($"[PlayerCombat] {message}", gameObject);
|
|
}
|
|
}
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
// Draw attack range
|
|
Gizmos.color = Color.red;
|
|
Gizmos.DrawWireSphere(transform.position, attackRange);
|
|
|
|
// Draw max chase distance
|
|
Gizmos.color = Color.yellow;
|
|
Gizmos.DrawWireSphere(transform.position, maxChaseDistance);
|
|
}
|
|
}
|