using System; using System.Collections.Generic; using UnityEngine; using Unity.Behavior; namespace Colosseum.Enemy { /// /// 보스 페이즈 전환 조건 타입 /// public enum PhaseTransitionType { HealthPercent, // 체력 비율 기반 TimeElapsed, // 시간 경과 CustomCondition, // 커스텀 조건 (코드에서 설정) Manual, // 수동 전환 } /// /// 보스 페이즈 데이터. 각 페이즈의 AI, 조건, 보상을 정의합니다. /// [CreateAssetMenu(fileName = "NewBossPhase", menuName = "Colosseum/Boss Phase")] public class BossPhaseData : ScriptableObject { [Header("페이즈 정보")] [SerializeField] private string phaseName = "Phase 1"; [TextArea(1, 3)] [SerializeField] private string description; [Header("전환 조건")] [SerializeField] private PhaseTransitionType transitionType = PhaseTransitionType.HealthPercent; [Tooltip("체력 비율 기반 전환 시, 이 비율 이하에서 페이즈 전환")] [Range(0f, 1f)] [SerializeField] private float healthPercentThreshold = 0.7f; [Tooltip("시간 기반 전환 시, 경과 시간 (초)")] [Min(0f)] [SerializeField] private float timeThreshold = 60f; [Tooltip("커스텀 조건 ID (코드에서 사용)")] [SerializeField] private string customConditionId; [Header("AI 설정")] [Tooltip("이 페이즈에서 사용할 Behavior Graph")] [SerializeField] private BehaviorGraph behaviorGraph; [Tooltip("페이즈 전환 시 Blackboard 변수 오버라이드")] [SerializeField] private List blackboardOverrides = new(); [Header("페이즈 효과")] [Tooltip("페이즈 시작 시 재생할 애니메이션")] [SerializeField] private AnimationClip phaseStartAnimation; [Tooltip("페이즈 전환 효과 (이펙트, 사운드 등)")] [SerializeField] private GameObject phaseTransitionEffect; // Properties public string PhaseName => phaseName; public string Description => description; public PhaseTransitionType TransitionType => transitionType; public float HealthPercentThreshold => healthPercentThreshold; public float TimeThreshold => timeThreshold; public string CustomConditionId => customConditionId; public BehaviorGraph BehaviorGraph => behaviorGraph; public IReadOnlyList BlackboardOverrides => blackboardOverrides; public AnimationClip PhaseStartAnimation => phaseStartAnimation; public GameObject PhaseTransitionEffect => phaseTransitionEffect; /// /// 전환 조건 충족 여부 확인 /// public bool CheckTransitionCondition(BossEnemy boss, float elapsedTime) { BossBehaviorRuntimeState context = boss != null ? boss.GetComponent() : null; return transitionType switch { PhaseTransitionType.HealthPercent => boss.CurrentHealth / boss.MaxHealth <= healthPercentThreshold, PhaseTransitionType.TimeElapsed => elapsedTime >= timeThreshold, PhaseTransitionType.CustomCondition => context != null && context.CheckPhaseCustomCondition(customConditionId), PhaseTransitionType.Manual => false, _ => false, }; } } /// /// Blackboard 변수 오버라이드 정보 /// [Serializable] public class BlackboardVariableOverride { [Tooltip("변수 이름")] [SerializeField] private string variableName; [Tooltip("변수 타입")] [SerializeField] private BlackboardVariableType variableType = BlackboardVariableType.Float; [Tooltip("설정할 값")] [SerializeField] private float floatValue; [SerializeField] private int intValue; [SerializeField] private bool boolValue; [SerializeField] private string stringValue; [SerializeField] private GameObject gameObjectValue; public string VariableName => variableName; public BlackboardVariableType VariableType => variableType; public float FloatValue => floatValue; public int IntValue => intValue; public bool BoolValue => boolValue; public string StringValue => stringValue; public GameObject GameObjectValue => gameObjectValue; } /// /// Blackboard 변수 타입 /// public enum BlackboardVariableType { Float, Int, Bool, String, GameObject, } }