105 lines
2.8 KiB
C#
105 lines
2.8 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);
|
|
}
|
|
}
|
|
} |