using System; using Colosseum.Abnormalities; using Colosseum.Combat; using Colosseum.Player; using Unity.Behavior; using Unity.Properties; using UnityEngine; using Action = Unity.Behavior.Action; /// /// 충전 차단에 실패하여 패턴이 완료되었을 때, 전체 플레이어에게 범위 효과를 적용합니다. /// 필요한 수치는 BT 노드 필드에서 직접 설정합니다. /// [Serializable, GeneratePropertyBag] [NodeDescription( name: "Signature Failure Effects", story: "패턴 완료 범위 효과 적용", category: "Action", id: "c3d4e5f6-1111-2222-3333-777788889999")] public partial class SignatureFailureEffectsAction : Action { [SerializeReference] public BlackboardVariable FailureDamage = new BlackboardVariable(40f); [SerializeReference] public BlackboardVariable FailureAbnormality; [SerializeReference] public BlackboardVariable KnockbackRadius = new BlackboardVariable(8f); [SerializeReference] public BlackboardVariable DownRadius = new BlackboardVariable(3f); [SerializeReference] public BlackboardVariable KnockbackSpeed = new BlackboardVariable(12f); [SerializeReference] public BlackboardVariable KnockbackDuration = new BlackboardVariable(0.35f); [SerializeReference] public BlackboardVariable DownDuration = new BlackboardVariable(2f); protected override Status OnStart() { ApplyFailureEffects(); return Status.Success; } private void ApplyFailureEffects() { float failureDamage = Mathf.Max(0f, FailureDamage?.Value ?? 0f); AbnormalityData failureAbnormality = FailureAbnormality?.Value; float knockbackRadius = Mathf.Max(0f, KnockbackRadius?.Value ?? 0f); float downRadius = Mathf.Max(0f, DownRadius?.Value ?? 0f); float knockbackSpeed = Mathf.Max(0f, KnockbackSpeed?.Value ?? 0f); float knockbackDuration = Mathf.Max(0f, KnockbackDuration?.Value ?? 0f); float downDuration = Mathf.Max(0f, DownDuration?.Value ?? 0f); PlayerNetworkController[] players = UnityEngine.Object.FindObjectsByType(FindObjectsSortMode.None); for (int i = 0; i < players.Length; i++) { PlayerNetworkController player = players[i]; if (player == null || player.IsDead || !player.gameObject.activeInHierarchy) continue; GameObject target = player.gameObject; player.TakeDamage(failureDamage, GameObject); if (failureAbnormality != null) { AbnormalityManager targetAbnormalityManager = target.GetComponent(); targetAbnormalityManager?.ApplyAbnormality(failureAbnormality, GameObject); } HitReactionController hitReactionController = target.GetComponent(); if (hitReactionController == null) continue; float distance = Vector3.Distance(GameObject.transform.position, target.transform.position); if (distance <= downRadius) { hitReactionController.ApplyDown(downDuration); continue; } if (distance > knockbackRadius) continue; Vector3 knockbackDirection = target.transform.position - GameObject.transform.position; knockbackDirection.y = 0f; if (knockbackDirection.sqrMagnitude < 0.0001f) { knockbackDirection = GameObject.transform.forward; } hitReactionController.ApplyKnockback(knockbackDirection.normalized * knockbackSpeed, knockbackDuration); } CombatBalanceTracker.RecordBossEvent("집행 개시 실패"); } }