using System; using Colosseum.AI; using Colosseum.Enemy; using Unity.Behavior; using Unity.Properties; using UnityEngine; /// /// 지정된 패턴을 실행하는 범용 액션 노드입니다. /// Pattern 필드에 BossPatternData 에셋을 직접 할당합니다. /// 타겟 해석과 등록은 Condition에서 처리되므로, 이 액션은 순수하게 패턴만 실행합니다. /// 시그니처 패턴도 일반 패턴과 동일하게 BossPatternActionBase의 스텝 루프로 실행됩니다. /// ChargeWait 스텝이 차단/완료 판정을 담당합니다. /// [Serializable, GeneratePropertyBag] [NodeDescription( name: "Use Pattern By Role", story: "[Pattern] 패턴 실행", category: "Action", id: "b2c3d4e5-1111-2222-3333-555566667777")] public partial class UsePatternByRoleAction : BossPatternActionBase { [SerializeReference] [Tooltip("실행할 패턴")] public BlackboardVariable Pattern; protected override Status OnStart() { BossPatternData pattern = Pattern?.Value; if (pattern == null) return Status.Failure; // 타겟 해석은 ResolveStepTarget에서 처리됨 // 여기서는 RegisterPatternUse만 호출 (근접 패턴 전용) if (pattern.IsMelee) { BossCombatBehaviorContext context = GameObject.GetComponent(); context?.RegisterPatternUse(pattern); } // base.OnStart는 TryResolvePattern → ExecuteCurrentStep 호출 return base.OnStart(); } protected override Status OnUpdate() { return base.OnUpdate(); } protected override void OnEnd() { base.OnEnd(); } /// /// BossPatternActionBase.TryResolvePattern 구현. /// Condition에서 이미 타겟을 해석했으므로, Target.Value를 그대로 사용합니다. /// protected override bool TryResolvePattern(out BossPatternData pattern, out GameObject target) { pattern = Pattern?.Value; target = Target != null ? Target.Value : null; if (pattern == null) return false; if (!UsePatternAction.IsPatternReady(GameObject, pattern)) return false; if (target == null) return false; return true; } protected override GameObject ResolveStepTarget(GameObject fallbackTarget) { BossPatternData pattern = Pattern?.Value; if (pattern == null) return base.ResolveStepTarget(fallbackTarget); BossCombatBehaviorContext context = GameObject.GetComponent(); if (context == null) return base.ResolveStepTarget(fallbackTarget); TargetResolveMode targetMode = pattern.TargetMode; if (targetMode == TargetResolveMode.Mobility) return context.IsValidMobilityTarget(fallbackTarget) ? fallbackTarget : context.FindMobilityTarget(); if (targetMode == TargetResolveMode.Utility) return context.IsValidUtilityTarget(fallbackTarget) ? fallbackTarget : context.FindUtilityTarget(); return base.ResolveStepTarget(fallbackTarget); } }