using System; using Colosseum; using Colosseum.Combat; using Colosseum.Enemy; using Colosseum.Player; using Unity.Behavior; using Unity.Properties; using UnityEngine; using Action = Unity.Behavior.Action; /// /// 일정 반경 내에서 가장 가까운 다운 대상 플레이어를 선택하는 Behavior Action입니다. /// [Serializable, GeneratePropertyBag] [NodeDescription( name: "Select Nearest Downed Target", story: "[SearchRadius] 반경 내 가장 가까운 다운 대상을 [Target]으로 선택", category: "Action", id: "ee1146ad46ec4730acb4d6c883a5a771")] public partial class SelectNearestDownedTargetAction : Action { [SerializeReference] public BlackboardVariable Target; [SerializeReference] public BlackboardVariable SearchRadius = new BlackboardVariable(0f); protected override Status OnStart() { float searchRadius = ResolveSearchRadius(); HitReactionController[] hitReactionControllers = UnityEngine.Object.FindObjectsByType(FindObjectsSortMode.None); GameObject nearestTarget = null; float nearestDistance = float.MaxValue; for (int i = 0; i < hitReactionControllers.Length; i++) { HitReactionController controller = hitReactionControllers[i]; if (controller == null || !controller.IsDowned) continue; GameObject candidate = controller.gameObject; if (candidate == null || !candidate.activeInHierarchy) continue; if (Team.IsSameTeam(GameObject, candidate)) continue; IDamageable damageable = candidate.GetComponent(); if (damageable != null && damageable.IsDead) continue; float distance = TargetSurfaceUtility.GetHorizontalSurfaceDistance(GameObject.transform.position, candidate); if (distance > searchRadius || distance >= nearestDistance) continue; nearestDistance = distance; nearestTarget = candidate; } if (nearestTarget == null) return Status.Failure; Target.Value = nearestTarget; GameObject.GetComponent()?.SetCurrentTarget(nearestTarget); LogDebug($"다운 대상 선택: {nearestTarget.name}"); return Status.Success; } private float ResolveSearchRadius() { return Mathf.Max(0f, SearchRadius.Value); } private void LogDebug(string message) { BossBehaviorRuntimeState context = GameObject.GetComponent(); context?.LogDebug(nameof(SelectNearestDownedTargetAction), message); } }