Files
beyond/Assets/AI/_Archer/DEC_PlayerTooClose.cs
2025-11-20 14:34:59 +01:00

80 lines
2.3 KiB
C#

using Invector.vCharacterController.AI.FSMBehaviour;
using UnityEngine;
namespace ArcherEnemy
{
/// <summary>
/// Decision checking if player is too close to the archer
/// Used to trigger retreat/flee behavior
/// </summary>
[CreateAssetMenu(menuName = "Invector/FSM/Decisions/Archer/Player Too Close")]
public class DEC_PlayerTooClose : vStateDecision
{
public override string categoryName => "Archer/Combat";
public override string defaultName => "Player Too Close";
[Header("Distance Configuration")]
[Tooltip("Distance below which player is considered too close")]
public float dangerDistance = 6f;
[Tooltip("Optional: check only if player is approaching (not retreating)")]
public bool checkIfApproaching = false;
[Header("Debug")]
[Tooltip("Enable debug logging")]
public bool enableDebug = false;
private Vector3 lastPlayerPosition;
private bool hasLastPosition = false;
public override bool Decide(vIFSMBehaviourController fsmBehaviour)
{
Transform target = GetTarget(fsmBehaviour);
if (target == null)
{
if (enableDebug) Debug.Log("[DEC_PlayerTooClose] No target found");
hasLastPosition = false;
return false;
}
float distance = Vector3.Distance(fsmBehaviour.transform.position, target.position);
bool tooClose = distance < dangerDistance;
// Optional: check if player is approaching
if (checkIfApproaching && hasLastPosition)
{
float previousDistance = Vector3.Distance(fsmBehaviour.transform.position, lastPlayerPosition);
bool isApproaching = distance < previousDistance;
if (!isApproaching)
{
tooClose = false; // Player is moving away, not a threat
}
}
// Store current position for next frame
lastPlayerPosition = target.position;
hasLastPosition = true;
if (enableDebug)
{
Debug.Log($"[DEC_PlayerTooClose] Distance: {distance:F1}m - {(tooClose ? "TOO CLOSE" : "SAFE")}");
}
return tooClose;
}
private Transform GetTarget(vIFSMBehaviourController fsmBehaviour)
{
// Try through AI controller
var aiController = fsmBehaviour as Invector.vCharacterController.AI.vIControlAI;
if (aiController != null && aiController.currentTarget != null)
return aiController.currentTarget.transform;
// Fallback - find player
GameObject player = GameObject.FindGameObjectWithTag("Player");
return player?.transform;
}
}
}