using Invector.vCharacterController.AI.FSMBehaviour; using Lean.Pool; using UnityEngine; namespace DemonBoss.Magic { /// /// Spawns a meteor behind the BOSS and launches it toward the player's position /// Similar mechanics to FireballProjectile but coming from above /// [CreateAssetMenu(menuName = "Invector/FSM/Actions/DemonBoss/Call Meteor")] public class SA_CallMeteor : vStateAction { public override string categoryName => "DemonBoss/Magic"; public override string defaultName => "Call Meteor"; [Header("Meteor Setup")] [Tooltip("Prefab with MeteorProjectile component")] public GameObject meteorPrefab; [Tooltip("Distance behind the BOSS to spawn meteor (meters)")] public float behindBossDistance = 3f; [Tooltip("Height above the BOSS to spawn meteor (meters)")] public float aboveBossHeight = 8f; [Tooltip("Delay before meteor spawns (wind-up)")] public float castDelay = 0.4f; [Header("Targeting")] [Tooltip("Tag used to find the target (usually Player)")] public string targetTag = "Player"; [Header("Debug")] public bool enableDebug = false; private Transform _boss; private Transform _target; public override void DoAction(vIFSMBehaviourController fsm, vFSMComponentExecutionType execType = vFSMComponentExecutionType.OnStateUpdate) { if (execType == vFSMComponentExecutionType.OnStateEnter) { OnEnter(fsm); } } private void OnEnter(vIFSMBehaviourController fsm) { _boss = fsm.transform; _target = GameObject.FindGameObjectWithTag(targetTag)?.transform; if (_target == null) { if (enableDebug) Debug.LogWarning("[SA_CallMeteor] No target found – abort"); return; } if (enableDebug) Debug.Log($"[SA_CallMeteor] Boss: {_boss.name}, Target: {_target.name}"); SpawnMeteor(); } private void SpawnMeteor() { if (meteorPrefab == null) { if (enableDebug) Debug.LogError("[SA_CallMeteor] Missing meteorPrefab"); return; } if (_boss == null || _target == null) { if (enableDebug) Debug.LogError("[SA_CallMeteor] Missing boss or target reference"); return; } // Calculate spawn position: behind the BOSS + height Vector3 bossForward = _boss.forward.normalized; Vector3 behindBoss = _boss.position - (bossForward * behindBossDistance); Vector3 spawnPos = behindBoss + Vector3.up * aboveBossHeight; if (enableDebug) Debug.Log($"[SA_CallMeteor] Spawning meteor at: {spawnPos}"); // Spawn the meteor var meteorGO = LeanPool.Spawn(meteorPrefab, spawnPos, Quaternion.identity); // Configure the projectile to target the player var meteorScript = meteorGO.GetComponent(); if (meteorScript != null) { // Set it to target the player's current position meteorScript.useOverrideImpactPoint = true; meteorScript.overrideImpactPoint = _target.position; meteorScript.snapImpactToGround = true; if (enableDebug) Debug.Log($"[SA_CallMeteor] Meteor configured to target: {_target.position}"); } else { if (enableDebug) Debug.LogError("[SA_CallMeteor] Meteor prefab missing MeteorProjectile component!"); } } } }