feat: 드로그 보스 AI 및 런타임 상태 구조 재구성
- 드로그 전투 컨텍스트를 BossBehaviorRuntimeState 중심 구조로 정리하고 BossEnemy, 패턴 액션, 조건 노드가 마지막 실행 결과와 phase 상태를 직접 사용하도록 갱신 - BT_Drog와 재빌드 에디터 스크립트를 확장해 phase 전환, 집행 결과 분기, 거리/쿨타임 기반 패턴 선택을 드로그 전용 자산과 노드 파라미터로 재구성 - 드로그 패턴/스킬/이펙트/애니메이션 플레이스홀더 자산을 재생성하고 보스 프리팹이 새 런타임 상태 및 등록 클립 구성을 참조하도록 정리
This commit is contained in:
@@ -13,16 +13,19 @@ namespace Colosseum.Editor
|
||||
public class BossEnemyEditor : UnityEditor.Editor
|
||||
{
|
||||
private BossEnemy boss;
|
||||
private BossBehaviorRuntimeState bossContext;
|
||||
private bool showPhaseDetails = true;
|
||||
private bool showThreatInfo = true;
|
||||
private bool showDebugTools = true;
|
||||
private int selectedPhaseIndex = 0;
|
||||
private float debugHPPercent = 1f;
|
||||
private float debugHPValue = 0f;
|
||||
private string customConditionId = "Enraged";
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
boss = (BossEnemy)target;
|
||||
bossContext = boss != null ? boss.GetComponent<BossBehaviorRuntimeState>() : null;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
@@ -70,14 +73,11 @@ namespace Colosseum.Editor
|
||||
DrawProgressBar("HP", hpPercent, GetHealthColor(hpPercent), $"{boss.CurrentHealth:F0} / {boss.MaxHealth:F0}");
|
||||
|
||||
// 상태 정보
|
||||
EditorGUILayout.LabelField("현재 페이즈", $"{boss.CurrentPhaseIndex + 1} / {boss.TotalPhases}");
|
||||
EditorGUILayout.LabelField("현재 페이즈", bossContext != null
|
||||
? $"{bossContext.CurrentPatternPhase} / {bossContext.MaxPatternPhase}"
|
||||
: "N/A");
|
||||
EditorGUILayout.LabelField("상태", GetStatusText());
|
||||
|
||||
if (boss.CurrentPhase != null)
|
||||
{
|
||||
EditorGUILayout.LabelField("페이즈명", boss.CurrentPhase.PhaseName);
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
@@ -93,53 +93,16 @@ namespace Colosseum.Editor
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
var phasesProp = serializedObject.FindProperty("phases");
|
||||
if (phasesProp == null || phasesProp.arraySize == 0)
|
||||
if (bossContext == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("등록된 페이즈가 없습니다.", MessageType.Warning);
|
||||
EditorGUILayout.HelpBox("BossBehaviorRuntimeState를 찾지 못했습니다.", MessageType.Warning);
|
||||
EditorGUI.indentLevel--;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < phasesProp.arraySize; i++)
|
||||
{
|
||||
var phaseProp = phasesProp.GetArrayElementAtIndex(i);
|
||||
var phase = phaseProp.objectReferenceValue as BossPhaseData;
|
||||
|
||||
if (phase == null)
|
||||
continue;
|
||||
|
||||
bool isCurrentPhase = i == boss.CurrentPhaseIndex;
|
||||
bool isCompleted = i < boss.CurrentPhaseIndex;
|
||||
|
||||
// 페이즈 헤더
|
||||
GUIStyle phaseStyle = new GUIStyle(EditorStyles.foldout);
|
||||
if (isCurrentPhase)
|
||||
phaseStyle.fontStyle = FontStyle.Bold;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
// 상태 아이콘
|
||||
string statusIcon = isCurrentPhase ? "▶" : (isCompleted ? "✓" : "○");
|
||||
GUIContent phaseLabel = new GUIContent($"{statusIcon} Phase {i + 1}: {phase.PhaseName}");
|
||||
|
||||
EditorGUILayout.LabelField(phaseLabel, GUILayout.Width(200));
|
||||
|
||||
// 전환 조건
|
||||
EditorGUILayout.LabelField($"[{phase.TransitionType}]", EditorStyles.miniLabel, GUILayout.Width(100));
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (isCurrentPhase)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.LabelField($"전환 조건: {GetTransitionConditionText(phase)}");
|
||||
EditorGUILayout.LabelField($"경과 시간: {boss.PhaseElapsedTime:F1}초");
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(2);
|
||||
}
|
||||
EditorGUILayout.LabelField("현재 Phase", bossContext.CurrentPatternPhase.ToString());
|
||||
EditorGUILayout.LabelField("최대 Phase", bossContext.MaxPatternPhase.ToString());
|
||||
EditorGUILayout.LabelField("경과 시간", $"{bossContext.PhaseElapsedTime:F1}초");
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
@@ -191,12 +154,13 @@ namespace Colosseum.Editor
|
||||
// 페이즈 강제 전환
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("페이즈 강제 전환", GUILayout.Width(120));
|
||||
selectedPhaseIndex = EditorGUILayout.IntSlider(selectedPhaseIndex, 0, Mathf.Max(0, boss.TotalPhases - 1));
|
||||
int maxPhaseIndex = bossContext != null ? Mathf.Max(0, bossContext.MaxPatternPhase - 1) : 0;
|
||||
selectedPhaseIndex = EditorGUILayout.IntSlider(selectedPhaseIndex, 0, maxPhaseIndex);
|
||||
if (GUILayout.Button("전환", GUILayout.Width(60)))
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
if (Application.isPlaying && bossContext != null)
|
||||
{
|
||||
boss.ForcePhaseTransition(selectedPhaseIndex);
|
||||
bossContext.SetCurrentPatternPhase(selectedPhaseIndex + 1);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
@@ -206,9 +170,9 @@ namespace Colosseum.Editor
|
||||
// 현재 페이즈 재시작
|
||||
if (GUILayout.Button("현재 페이즈 재시작"))
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
if (Application.isPlaying && bossContext != null)
|
||||
{
|
||||
boss.RestartCurrentPhase();
|
||||
bossContext.RestartCurrentPhaseTimer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,17 +236,17 @@ namespace Colosseum.Editor
|
||||
EditorGUILayout.LabelField("커스텀 조건 설정", EditorStyles.boldLabel);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("조건 ID:", GUILayout.Width(60));
|
||||
string conditionId = EditorGUILayout.TextField("Enraged");
|
||||
customConditionId = EditorGUILayout.TextField(customConditionId);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("활성화"))
|
||||
{
|
||||
boss.SetCustomCondition(conditionId, true);
|
||||
bossContext?.SetPhaseCustomCondition(customConditionId, true);
|
||||
}
|
||||
if (GUILayout.Button("비활성화"))
|
||||
{
|
||||
boss.SetCustomCondition(conditionId, false);
|
||||
bossContext?.SetPhaseCustomCondition(customConditionId, false);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
@@ -359,25 +323,8 @@ namespace Colosseum.Editor
|
||||
{
|
||||
if (boss.IsDead)
|
||||
return "<color=red>사망</color>";
|
||||
if (boss.IsTransitioning)
|
||||
return "<color=yellow>페이즈 전환 중</color>";
|
||||
return "<color=green>활성</color>";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 전환 조건 텍스트 반환
|
||||
/// </summary>
|
||||
private string GetTransitionConditionText(BossPhaseData phase)
|
||||
{
|
||||
return phase.TransitionType switch
|
||||
{
|
||||
PhaseTransitionType.HealthPercent => $"HP ≤ {phase.HealthPercentThreshold * 100:F0}%",
|
||||
PhaseTransitionType.TimeElapsed => $"시간 ≥ {phase.TimeThreshold:F0}초",
|
||||
PhaseTransitionType.CustomCondition => $"조건: {phase.CustomConditionId}",
|
||||
PhaseTransitionType.Manual => "수동 전환",
|
||||
_ => "알 수 없음"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user