Files
beyond/Assets/AI/Demon/DEC_TargetClearSky.cs
2025-08-11 13:34:13 +02:00

105 lines
2.7 KiB
C#

using Invector.vCharacterController.AI.FSMBehaviour;
using UnityEngine;
namespace DemonBoss.Magic
{
/// <summary>
/// Decision checking if target has clear sky above (for meteor)
/// </summary>
[CreateAssetMenu(menuName = "Invector/FSM/Decisions/DemonBoss/Target Clear Sky")]
public class DEC_TargetClearSky : vStateDecision
{
public override string categoryName => "DemonBoss/Magic";
public override string defaultName => "Target Clear Sky";
[Header("Sky Check Configuration")]
[Tooltip("Check height above target")]
public float checkHeight = 25f;
[Tooltip("Obstacle check radius")]
public float checkRadius = 2f;
[Tooltip("Obstacle layer mask")]
public LayerMask obstacleLayerMask = -1;
[Header("Debug")]
[Tooltip("Enable debug logging")]
public bool enableDebug = false;
[Tooltip("Show gizmos in Scene View")]
public bool showGizmos = true;
public override bool Decide(vIFSMBehaviourController fsmBehaviour)
{
Transform target = GetTarget(fsmBehaviour);
if (target == null)
{
if (enableDebug) Debug.Log("[DEC_TargetClearSky] No target found");
return false;
}
bool isClear = IsSkyClear(target.position);
if (enableDebug)
{
Debug.Log($"[DEC_TargetClearSky] Sky above target: {(isClear ? "CLEAR" : "BLOCKED")}");
}
return isClear;
}
private bool IsSkyClear(Vector3 targetPosition)
{
Vector3 skyCheckPoint = targetPosition + Vector3.up * checkHeight;
if (Physics.CheckSphere(skyCheckPoint, checkRadius, obstacleLayerMask))
{
return false;
}
Ray skyRay = new Ray(skyCheckPoint, Vector3.down);
RaycastHit[] hits = Physics.RaycastAll(skyRay, checkHeight, obstacleLayerMask);
foreach (var hit in hits)
{
if (hit.point.y <= targetPosition.y + 0.5f) continue;
return false;
}
return true;
}
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;
}
private void OnDrawGizmosSelected()
{
if (!showGizmos) return;
GameObject player = GameObject.FindGameObjectWithTag("Player");
if (player == null) return;
Vector3 targetPos = player.transform.position;
Vector3 skyCheckPoint = targetPos + Vector3.up * checkHeight;
Gizmos.color = Color.cyan;
Gizmos.DrawWireSphere(skyCheckPoint, checkRadius);
Gizmos.color = Color.yellow;
Gizmos.DrawLine(targetPos, skyCheckPoint);
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(targetPos, 0.5f);
}
}
}