using Invector.vCharacterController.AI.FSMBehaviour; using UnityEngine; namespace DemonBoss.Magic { /// /// Decision checking if target has clear sky above (for meteor) /// [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); } } }