using UnityEngine; // 임포트할거에요 -> Unity 엔진 기본 기능을 using UnityEngine.UI; // 임포트할거에요 -> Unity UI 시스템을 using UnityEditor; // 임포트할거에요 -> Unity 에디터 전용 기능을 using TMPro; // 임포트할거에요 -> TextMeshPro를 // ══════════════════════════════════════════════════════════════════════ // BossHealthBarCreator — 에디터 유틸리티 (다크 판타지 스타일) // // 디자인 레퍼런스: 화면 상단 풀 와이드, 얇은 HP 바, // 좌측 보스 이름, 어두운 프레임, 페이즈 구분선 // // 사용법: Unity 상단 메뉴 → Tools → Boss Health Bar → Create Boss HealthBar UI // ※ 에디터 전용 스크립트 — 빌드에 포함되지 않음 // ══════════════════════════════════════════════════════════════════════ public static class BossHealthBarCreator // 정적 클래스를 정의할거에요 -> 에디터 유틸리티 클래스를 { // ───────────────────────────────────────────────────────────── // 상수 — 다크 판타지 디자인 수치 // ───────────────────────────────────────────────────────────── private const float BAR_WIDTH = 750f; // 상수를 정의할거에요 -> 체력바 전체 너비를 (풀 와이드 느낌) private const float BAR_HEIGHT = 16f; // 상수를 정의할거에요 -> 체력바 높이를 (얇은 바) private const float ROOT_HEIGHT = 52f; // 상수를 정의할거에요 -> 루트 전체 높이를 (이름 + 바) private const float FRAME_PADDING_H = 12f; // 상수를 정의할거에요 -> 프레임 좌우 여백을 private const float FRAME_PADDING_V = 6f; // 상수를 정의할거에요 -> 프레임 상하 여백을 private const float DIVIDER_WIDTH = 1.5f; // 상수를 정의할거에요 -> 구분선 너비를 (가는 선) private const float TOP_OFFSET_Y = -20f; // 상수를 정의할거에요 -> 화면 상단에서의 Y 오프셋을 (바짝 붙임) private const float NAME_FONT_SIZE = 16f; // 상수를 정의할거에요 -> 보스 이름 폰트 크기를 private const float HP_FONT_SIZE = 11f; // 상수를 정의할거에요 -> HP 수치 폰트 크기를 // ───────────────────────────────────────────────────────────── // 색상 팔레트 — 다크 판타지 테마 // ───────────────────────────────────────────────────────────── private static readonly Color COL_FRAME_BG = new Color(0.06f, 0.05f, 0.07f, 0.88f); // 프레임 배경 (거의 검정) private static readonly Color COL_FRAME_BORDER = new Color(0.35f, 0.25f, 0.15f, 0.7f); // 프레임 테두리 (어두운 갈색) private static readonly Color COL_FRAME_INNER = new Color(0.25f, 0.18f, 0.12f, 0.5f); // 안쪽 라인 (바랜 갈색) private static readonly Color COL_BAR_BG = new Color(0.08f, 0.06f, 0.06f, 0.95f); // 바 배경 (짙은 검정) private static readonly Color COL_HP_FILL = new Color(0.6f, 0.12f, 0.08f, 1f); // HP 바 (어두운 붉은색) private static readonly Color COL_DAMAGE_FILL = new Color(0.7f, 0.3f, 0.1f, 0.6f); // 데미지 연출 (어두운 주황) private static readonly Color COL_NAME_TEXT = new Color(0.85f, 0.78f, 0.65f, 1f); // 보스 이름 (바랜 금색) private static readonly Color COL_HP_TEXT = new Color(0.7f, 0.65f, 0.55f, 0.85f); // HP 수치 (어두운 금색) private static readonly Color COL_DIVIDER = new Color(0.5f, 0.4f, 0.25f, 0.45f); // 구분선 (어두운 금색 반투명) private static readonly Color COL_DECO_LINE = new Color(0.4f, 0.3f, 0.18f, 0.35f); // 장식 라인 (은은한 갈색) // ───────────────────────────────────────────────────────────── // 메뉴 항목 // ───────────────────────────────────────────────────────────── [MenuItem("Tools/Boss Health Bar/Create Boss HealthBar UI")] // 메뉴를 등록할거에요 -> Tools 하위에 public static void CreateBossHealthBarUI() // 함수를 정의할거에요 -> 체력바 UI 자동 생성을 { // ════════════════════════════════════════════════════════ // 1단계: 기존 Canvas 찾기 또는 새로 생성 // ════════════════════════════════════════════════════════ Canvas existingCanvas = Object.FindObjectOfType(); // 찾을거에요 -> 씬에 이미 있는 Canvas를 GameObject canvasObj; // 변수를 선언할거에요 -> Canvas 오브젝트를 if (existingCanvas != null) // 조건이 맞으면 실행할거에요 -> 기존 Canvas가 있으면 { canvasObj = existingCanvas.gameObject; // 사용할거에요 -> 기존 Canvas를 그대로 Debug.Log("[BossHealthBarCreator] 기존 Canvas를 사용합니다."); // 로그를 찍을거에요 } else // 조건이 틀리면 실행할거에요 -> Canvas가 없으면 새로 생성 { canvasObj = new GameObject("InGameCanvas"); // 생성할거에요 -> Canvas 오브젝트를 Canvas canvas = canvasObj.AddComponent(); // 추가할거에요 -> Canvas 컴포넌트를 canvas.renderMode = RenderMode.ScreenSpaceOverlay; // 설정할거에요 -> 렌더 모드를 오버레이로 canvas.sortingOrder = 10; // 설정할거에요 -> 정렬 순서를 (다른 UI 위에) CanvasScaler scaler = canvasObj.AddComponent(); // 추가할거에요 -> CanvasScaler를 scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; // 설정할거에요 -> 해상도 대응 스케일 모드를 scaler.referenceResolution = new Vector2(1920, 1080); // 설정할거에요 -> 기준 해상도를 FHD로 scaler.matchWidthOrHeight = 0.5f; // 설정할거에요 -> 가로/세로 매칭 비율을 canvasObj.AddComponent(); // 추가할거에요 -> UI 클릭 감지용 Raycaster를 Debug.Log("[BossHealthBarCreator] 새 Canvas를 생성했습니다."); // 로그를 찍을거에요 } // ════════════════════════════════════════════════════════ // 2단계: BossHealthBar_Root (최상위 컨테이너) // → 화면 상단 중앙에 풀 와이드로 배치 // ════════════════════════════════════════════════════════ GameObject root = CreateUIObject("BossHealthBar_Root", canvasObj.transform); // 생성할거에요 -> 체력바 루트 오브젝트를 RectTransform rootRect = root.GetComponent(); // 가져올거에요 -> RectTransform을 rootRect.anchorMin = new Vector2(0.5f, 1f); // 설정할거에요 -> 앵커 최소를 (상단 중앙) rootRect.anchorMax = new Vector2(0.5f, 1f); // 설정할거에요 -> 앵커 최대를 (상단 중앙) rootRect.pivot = new Vector2(0.5f, 1f); // 설정할거에요 -> 피벗을 (상단 중앙) rootRect.anchoredPosition = new Vector2(0f, TOP_OFFSET_Y); // 설정할거에요 -> 위치를 (상단에서 살짝 아래) rootRect.sizeDelta = new Vector2(BAR_WIDTH, ROOT_HEIGHT); // 설정할거에요 -> 크기를 (750 × 52) // ════════════════════════════════════════════════════════ // 3단계: 외곽 테두리 (가장 뒤, 어두운 갈색) // ════════════════════════════════════════════════════════ GameObject outerBorder = CreateUIObject("OuterBorder", root.transform); // 생성할거에요 -> 외곽 테두리를 Image outerBorderImg = outerBorder.AddComponent(); // 추가할거에요 -> Image를 outerBorderImg.color = COL_FRAME_BORDER; // 설정할거에요 -> 어두운 갈색 테두리를 RectTransform outerBorderRect = outerBorder.GetComponent(); // 가져올거에요 -> RectTransform을 SetStretch(outerBorderRect); // 실행할거에요 -> 부모에 스트레치 outerBorderRect.offsetMin = new Vector2(-1.5f, -1.5f); // 설정할거에요 -> 바깥으로 1.5px 확장을 outerBorderRect.offsetMax = new Vector2(1.5f, 1.5f); // 설정할거에요 -> 바깥으로 1.5px 확장을 // ════════════════════════════════════════════════════════ // 4단계: 프레임 배경 (거의 검정, 메인 배경) // ════════════════════════════════════════════════════════ GameObject frame = CreateUIObject("Frame", root.transform); // 생성할거에요 -> 프레임 배경을 Image frameImg = frame.AddComponent(); // 추가할거에요 -> Image를 frameImg.color = COL_FRAME_BG; // 설정할거에요 -> 거의 검정색 배경을 RectTransform frameRect = frame.GetComponent(); // 가져올거에요 -> RectTransform을 SetStretch(frameRect); // 실행할거에요 -> 부모에 스트레치 // ════════════════════════════════════════════════════════ // 5단계: 안쪽 장식 라인 (프레임 내부 은은한 테두리) // ════════════════════════════════════════════════════════ GameObject innerLine = CreateUIObject("InnerLine", root.transform); // 생성할거에요 -> 안쪽 장식 라인을 Image innerLineImg = innerLine.AddComponent(); // 추가할거에요 -> Image를 innerLineImg.color = COL_FRAME_INNER; // 설정할거에요 -> 바랜 갈색 라인을 RectTransform innerLineRect = innerLine.GetComponent(); // 가져올거에요 -> RectTransform을 SetStretch(innerLineRect); // 실행할거에요 -> 부모에 스트레치 innerLineRect.offsetMin = new Vector2(3f, 3f); // 설정할거에요 -> 안쪽으로 3px 축소 innerLineRect.offsetMax = new Vector2(-3f, -3f); // 설정할거에요 -> 안쪽으로 3px 축소 // 안쪽은 투명하게 (테두리만 보이도록) // → Image를 쓰지만 배경 위에 겹쳐서 테두리 효과 // ════════════════════════════════════════════════════════ // 6단계: 좌측 장식 세로선 (이름 영역 구분) // ════════════════════════════════════════════════════════ GameObject leftDeco = CreateUIObject("LeftDecoLine", root.transform); // 생성할거에요 -> 좌측 장식 세로선을 Image leftDecoImg = leftDeco.AddComponent(); // 추가할거에요 -> Image를 leftDecoImg.color = COL_DECO_LINE; // 설정할거에요 -> 은은한 갈색을 RectTransform leftDecoRect = leftDeco.GetComponent(); // 가져올거에요 -> RectTransform을 leftDecoRect.anchorMin = new Vector2(0f, 0f); // 설정할거에요 -> 앵커를 좌측 전체로 leftDecoRect.anchorMax = new Vector2(0f, 1f); // 설정할거에요 -> 앵커를 좌측 전체로 leftDecoRect.pivot = new Vector2(0f, 0.5f); // 설정할거에요 -> 피벗을 좌측 중앙으로 leftDecoRect.anchoredPosition = new Vector2(160f, 0f); // 설정할거에요 -> 위치를 (이름 영역 끝) leftDecoRect.sizeDelta = new Vector2(1f, -10f); // 설정할거에요 -> 크기를 (1px 너비, 상하 5px 여유) // ════════════════════════════════════════════════════════ // 7단계: 보스 이름 텍스트 (좌측, 프레임 안) // ════════════════════════════════════════════════════════ GameObject nameObj = CreateUIObject("BossName", root.transform); // 생성할거에요 -> 이름 텍스트 오브젝트를 TextMeshProUGUI nameText = nameObj.AddComponent(); // 추가할거에요 -> TMP를 nameText.text = "Norciel"; // 설정할거에요 -> 기본 보스 이름을 nameText.fontSize = NAME_FONT_SIZE; // 설정할거에요 -> 폰트 크기를 16 nameText.fontStyle = FontStyles.Normal; // 설정할거에요 -> 일반 스타일을 (다크 판타지는 볼드보다 일반이 어울림) nameText.color = COL_NAME_TEXT; // 설정할거에요 -> 바랜 금색 텍스트를 nameText.alignment = TextAlignmentOptions.Center; // 설정할거에요 -> 중앙 정렬을 nameText.enableWordWrapping = false; // 설정할거에요 -> 줄바꿈 비활성화를 nameText.characterSpacing = 6f; // 설정할거에요 -> 자간을 넓혀서 (고풍스러운 느낌) RectTransform nameRect = nameObj.GetComponent(); // 가져올거에요 -> RectTransform을 nameRect.anchorMin = new Vector2(0f, 0f); // 설정할거에요 -> 앵커를 좌측 전체로 nameRect.anchorMax = new Vector2(0f, 1f); // 설정할거에요 -> 앵커를 좌측 전체로 nameRect.pivot = new Vector2(0f, 0.5f); // 설정할거에요 -> 피벗을 좌측 중앙으로 nameRect.anchoredPosition = new Vector2(FRAME_PADDING_H, 0f); // 설정할거에요 -> 위치를 (좌측 여백) nameRect.sizeDelta = new Vector2(145f, 0f); // 설정할거에요 -> 너비를 145px로 (높이는 스트레치) // ════════════════════════════════════════════════════════ // 8단계: 바 배경 (장식선 오른쪽, HP 바 영역) // ════════════════════════════════════════════════════════ float barStartX = 170f; // 설정할거에요 -> 바 시작 X를 (이름 영역 + 구분선 뒤) GameObject barBg = CreateUIObject("BarBackground", root.transform); // 생성할거에요 -> 바 배경을 Image barBgImg = barBg.AddComponent(); // 추가할거에요 -> Image를 barBgImg.color = COL_BAR_BG; // 설정할거에요 -> 짙은 검정 배경을 RectTransform barBgRect = barBg.GetComponent(); // 가져올거에요 -> RectTransform을 barBgRect.anchorMin = new Vector2(0f, 0.5f); // 설정할거에요 -> 앵커를 좌측 중앙으로 barBgRect.anchorMax = new Vector2(1f, 0.5f); // 설정할거에요 -> 앵커를 우측 중앙으로 barBgRect.pivot = new Vector2(0f, 0.5f); // 설정할거에요 -> 피벗을 좌측 중앙으로 barBgRect.anchoredPosition = new Vector2(barStartX, 0f); // 설정할거에요 -> 위치를 (이름 영역 오른쪽) barBgRect.sizeDelta = new Vector2(-barStartX - FRAME_PADDING_H, BAR_HEIGHT); // 설정할거에요 -> 크기를 (남은 너비 × 16px) // ════════════════════════════════════════════════════════ // 9단계: 데미지 연출 바 (어두운 주황, 뒤쪽에서 천천히 따라감) // ════════════════════════════════════════════════════════ GameObject damageFill = CreateUIObject("HP_DamageFill", barBg.transform); // 생성할거에요 -> 데미지 연출 바를 Image damageFillImg = damageFill.AddComponent(); // 추가할거에요 -> Image를 damageFillImg.color = COL_DAMAGE_FILL; // 설정할거에요 -> 어두운 주황색을 damageFillImg.type = Image.Type.Filled; // 설정할거에요 -> Filled 타입으로 damageFillImg.fillMethod = Image.FillMethod.Horizontal; // 설정할거에요 -> 가로 채우기를 damageFillImg.fillOrigin = 0; // 설정할거에요 -> 좌측부터 채우기를 damageFillImg.fillAmount = 1f; // 설정할거에요 -> 초기 100%를 SetStretch(damageFill.GetComponent()); // 실행할거에요 -> 부모에 스트레치 // ════════════════════════════════════════════════════════ // 10단계: HP 바 (어두운 붉은색, 실제 HP) // ════════════════════════════════════════════════════════ GameObject hpFill = CreateUIObject("HP_Fill", barBg.transform); // 생성할거에요 -> HP 바를 Image hpFillImg = hpFill.AddComponent(); // 추가할거에요 -> Image를 hpFillImg.color = COL_HP_FILL; // 설정할거에요 -> 어두운 붉은색을 hpFillImg.type = Image.Type.Filled; // 설정할거에요 -> Filled 타입으로 hpFillImg.fillMethod = Image.FillMethod.Horizontal; // 설정할거에요 -> 가로 채우기를 hpFillImg.fillOrigin = 0; // 설정할거에요 -> 좌측부터 채우기를 hpFillImg.fillAmount = 1f; // 설정할거에요 -> 초기 100%를 SetStretch(hpFill.GetComponent()); // 실행할거에요 -> 부모에 스트레치 // ════════════════════════════════════════════════════════ // 11단계: HP 바 위 그라디언트 하이라이트 (위쪽 밝은 선) // ════════════════════════════════════════════════════════ GameObject highlight = CreateUIObject("BarHighlight", barBg.transform); // 생성할거에요 -> 하이라이트를 Image highlightImg = highlight.AddComponent(); // 추가할거에요 -> Image를 highlightImg.color = new Color(1f, 1f, 1f, 0.06f); // 설정할거에요 -> 아주 연한 흰색을 (은은한 광택) RectTransform highlightRect = highlight.GetComponent(); // 가져올거에요 -> RectTransform을 highlightRect.anchorMin = new Vector2(0f, 0.6f); // 설정할거에요 -> 앵커를 (바 상단 40%) highlightRect.anchorMax = new Vector2(1f, 1f); // 설정할거에요 -> 앵커를 (바 최상단) highlightRect.offsetMin = Vector2.zero; // 설정할거에요 -> 여백 없음 highlightRect.offsetMax = Vector2.zero; // 설정할거에요 -> 여백 없음 // ════════════════════════════════════════════════════════ // 12단계: Phase2 구분선 (50% 지점) // ════════════════════════════════════════════════════════ GameObject phase2Div = CreatePhaseDivider("Phase2_Divider", barBg.transform, 0.5f); // 생성할거에요 -> Phase2 구분선 (50%) // ════════════════════════════════════════════════════════ // 13단계: Phase3 구분선 (25% 지점) // ════════════════════════════════════════════════════════ GameObject phase3Div = CreatePhaseDivider("Phase3_Divider", barBg.transform, 0.25f); // 생성할거에요 -> Phase3 구분선 (25%) // ════════════════════════════════════════════════════════ // 14단계: HP 수치 텍스트 (바 우측 끝) // ════════════════════════════════════════════════════════ GameObject hpTextObj = CreateUIObject("HP_Text", barBg.transform); // 생성할거에요 -> HP 수치 텍스트를 TextMeshProUGUI hpText = hpTextObj.AddComponent(); // 추가할거에요 -> TMP를 hpText.text = "1000 / 1000"; // 설정할거에요 -> 기본 텍스트를 hpText.fontSize = HP_FONT_SIZE; // 설정할거에요 -> 폰트 크기를 11 hpText.color = COL_HP_TEXT; // 설정할거에요 -> 어두운 금색을 hpText.alignment = TextAlignmentOptions.Right; // 설정할거에요 -> 우측 정렬을 (바 끝쪽) hpText.enableWordWrapping = false; // 설정할거에요 -> 줄바꿈 비활성화를 hpText.outlineWidth = 0.15f; // 설정할거에요 -> 얇은 외곽선을 hpText.outlineColor = new Color32(0, 0, 0, 200); // 설정할거에요 -> 검정 외곽선을 RectTransform hpTextRect = hpTextObj.GetComponent(); // 가져올거에요 -> RectTransform을 SetStretch(hpTextRect); // 실행할거에요 -> 부모에 스트레치 hpTextRect.offsetMax = new Vector2(-6f, 0f); // 설정할거에요 -> 우측에 6px 여백을 // ════════════════════════════════════════════════════════ // 15단계: 페이즈 텍스트 (이름 아래 작게) // ════════════════════════════════════════════════════════ GameObject phaseObj = CreateUIObject("Phase_Text", root.transform); // 생성할거에요 -> 페이즈 텍스트를 TextMeshProUGUI phaseTmp = phaseObj.AddComponent(); // 추가할거에요 -> TMP를 phaseTmp.text = "Phase 1"; // 설정할거에요 -> 기본 텍스트를 phaseTmp.fontSize = 10f; // 설정할거에요 -> 작은 폰트를 phaseTmp.color = new Color(0.5f, 0.45f, 0.35f, 0.6f); // 설정할거에요 -> 아주 어둡고 투명한 색을 phaseTmp.alignment = TextAlignmentOptions.Center; // 설정할거에요 -> 중앙 정렬을 phaseTmp.enableWordWrapping = false; // 설정할거에요 -> 줄바꿈 비활성화를 phaseTmp.characterSpacing = 4f; // 설정할거에요 -> 자간을 약간 넓게 RectTransform phaseRect = phaseObj.GetComponent(); // 가져올거에요 -> RectTransform을 phaseRect.anchorMin = new Vector2(0f, 0f); // 설정할거에요 -> 앵커를 좌하단으로 phaseRect.anchorMax = new Vector2(0f, 0f); // 설정할거에요 -> 앵커를 좌하단으로 phaseRect.pivot = new Vector2(0f, 1f); // 설정할거에요 -> 피벗을 좌상단으로 phaseRect.anchoredPosition = new Vector2(FRAME_PADDING_H, -2f); // 설정할거에요 -> 프레임 아래에 배치 phaseRect.sizeDelta = new Vector2(145f, 16f); // 설정할거에요 -> 이름 영역과 같은 너비 // ════════════════════════════════════════════════════════ // 16단계: BossHealthBarUI 컴포넌트 추가 + 참조 자동 연결 // ════════════════════════════════════════════════════════ BossHealthBarUI uiComponent = root.AddComponent(); // 추가할거에요 -> BossHealthBarUI 컴포넌트를 SerializedObject so = new SerializedObject(uiComponent); // 생성할거에요 -> SerializedObject를 (private 필드 접근용) so.FindProperty("hpFillImage").objectReferenceValue = hpFillImg; // 연결할거에요 -> HP Fill 이미지를 so.FindProperty("hpDamageFillImage").objectReferenceValue = damageFillImg; // 연결할거에요 -> 데미지 바를 so.FindProperty("bossNameText").objectReferenceValue = nameText; // 연결할거에요 -> 보스 이름을 so.FindProperty("hpValueText").objectReferenceValue = hpText; // 연결할거에요 -> HP 수치를 so.FindProperty("phaseText").objectReferenceValue = phaseTmp; // 연결할거에요 -> 페이즈 텍스트를 so.FindProperty("frameImage").objectReferenceValue = frameImg; // 연결할거에요 -> 프레임을 so.FindProperty("bossIconImage").objectReferenceValue = null; // 비워둘거에요 -> 아이콘 없음 (다크 판타지 스타일) so.FindProperty("phase2Divider").objectReferenceValue = phase2Div.GetComponent(); // 연결할거에요 -> Phase2 구분선을 so.FindProperty("phase3Divider").objectReferenceValue = phase3Div.GetComponent(); // 연결할거에요 -> Phase3 구분선을 so.ApplyModifiedProperties(); // 적용할거에요 -> 직렬화 데이터를 // ════════════════════════════════════════════════════════ // 17단계: 초기 상태 비활성화 // ════════════════════════════════════════════════════════ root.SetActive(false); // 비활성화할거에요 -> 전투 시작 전에는 숨김 // ════════════════════════════════════════════════════════ // 완료 // ════════════════════════════════════════════════════════ Undo.RegisterCreatedObjectUndo(root, "Create Boss HealthBar UI"); // 등록할거에요 -> Undo 기록을 Selection.activeGameObject = root; // 선택할거에요 -> 생성된 오브젝트를 Debug.Log("✅ [BossHealthBarCreator] 다크 판타지 보스 체력바 생성 완료! Inspector에서 Boss Monster / Phase Manager를 연결해주세요."); // 로그를 찍을거에요 } // ───────────────────────────────────────────────────────────── // 유틸리티 헬퍼 함수들 // ───────────────────────────────────────────────────────────── /// RectTransform 포함 빈 UI 오브젝트 생성 private static GameObject CreateUIObject(string name, Transform parent) // 헬퍼를 정의할거에요 -> UI 오브젝트 생성용 { GameObject obj = new GameObject(name); // 생성할거에요 -> 오브젝트를 obj.transform.SetParent(parent, false); // 설정할거에요 -> 부모를 if (obj.GetComponent() == null) // 조건이 맞으면 실행할거에요 -> RectTransform 없으면 obj.AddComponent(); // 추가할거에요 -> RectTransform을 return obj; // 반환할거에요 -> 오브젝트를 } /// RectTransform을 부모에 꽉 차게 스트레치 private static void SetStretch(RectTransform rect) // 헬퍼를 정의할거에요 -> 스트레치 설정용 { rect.anchorMin = Vector2.zero; // 설정할거에요 -> (0,0) rect.anchorMax = Vector2.one; // 설정할거에요 -> (1,1) rect.offsetMin = Vector2.zero; // 설정할거에요 -> 여백 없음 rect.offsetMax = Vector2.zero; // 설정할거에요 -> 여백 없음 } /// 페이즈 구분선 — 앵커 비율 기반 배치, 다크 판타지 색상 private static GameObject CreatePhaseDivider(string name, Transform parent, float ratio) // 헬퍼를 정의할거에요 -> 구분선 생성용 { GameObject divider = CreateUIObject(name, parent); // 생성할거에요 -> 구분선 오브젝트를 Image divImg = divider.AddComponent(); // 추가할거에요 -> Image를 divImg.color = COL_DIVIDER; // 설정할거에요 -> 어두운 금색 반투명을 RectTransform divRect = divider.GetComponent(); // 가져올거에요 -> RectTransform을 divRect.anchorMin = new Vector2(ratio, 0f); // 설정할거에요 -> 앵커를 (비율, 하단) divRect.anchorMax = new Vector2(ratio, 1f); // 설정할거에요 -> 앵커를 (비율, 상단) divRect.pivot = new Vector2(0.5f, 0.5f); // 설정할거에요 -> 피벗을 중앙으로 divRect.anchoredPosition = Vector2.zero; // 설정할거에요 -> 위치를 앵커 기준 divRect.sizeDelta = new Vector2(DIVIDER_WIDTH, 0f); // 설정할거에요 -> 너비 1.5px, 높이 스트레치 return divider; // 반환할거에요 -> 구분선을 } }