- ToonPostProcess.shader: 횃불 고딕 스타일 후처리 쉐이더 (Built-in RP) - ToonCameraEffect.cs: 카메라 자동 부착 후처리 스크립트 - 중복 UI 스크립트 제거 (MenuIntroController, ToggleCustom) - 씬, 프리팹, 애니메이션 등 전체 업데이트 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
335 lines
31 KiB
C#
335 lines
31 KiB
C#
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>(); // 찾을거에요 -> 씬에 이미 있는 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 컴포넌트를
|
||
canvas.renderMode = RenderMode.ScreenSpaceOverlay; // 설정할거에요 -> 렌더 모드를 오버레이로
|
||
canvas.sortingOrder = 10; // 설정할거에요 -> 정렬 순서를 (다른 UI 위에)
|
||
|
||
CanvasScaler scaler = canvasObj.AddComponent<CanvasScaler>(); // 추가할거에요 -> CanvasScaler를
|
||
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; // 설정할거에요 -> 해상도 대응 스케일 모드를
|
||
scaler.referenceResolution = new Vector2(1920, 1080); // 설정할거에요 -> 기준 해상도를 FHD로
|
||
scaler.matchWidthOrHeight = 0.5f; // 설정할거에요 -> 가로/세로 매칭 비율을
|
||
|
||
canvasObj.AddComponent<GraphicRaycaster>(); // 추가할거에요 -> UI 클릭 감지용 Raycaster를
|
||
Debug.Log("[BossHealthBarCreator] 새 Canvas를 생성했습니다."); // 로그를 찍을거에요
|
||
}
|
||
|
||
// ════════════════════════════════════════════════════════
|
||
// 2단계: BossHealthBar_Root (최상위 컨테이너)
|
||
// → 화면 상단 중앙에 풀 와이드로 배치
|
||
// ════════════════════════════════════════════════════════
|
||
GameObject root = CreateUIObject("BossHealthBar_Root", canvasObj.transform); // 생성할거에요 -> 체력바 루트 오브젝트를
|
||
RectTransform rootRect = root.GetComponent<RectTransform>(); // 가져올거에요 -> 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>(); // 추가할거에요 -> Image를
|
||
outerBorderImg.color = COL_FRAME_BORDER; // 설정할거에요 -> 어두운 갈색 테두리를
|
||
|
||
RectTransform outerBorderRect = outerBorder.GetComponent<RectTransform>(); // 가져올거에요 -> 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>(); // 추가할거에요 -> Image를
|
||
frameImg.color = COL_FRAME_BG; // 설정할거에요 -> 거의 검정색 배경을
|
||
|
||
RectTransform frameRect = frame.GetComponent<RectTransform>(); // 가져올거에요 -> RectTransform을
|
||
SetStretch(frameRect); // 실행할거에요 -> 부모에 스트레치
|
||
|
||
// ════════════════════════════════════════════════════════
|
||
// 5단계: 안쪽 장식 라인 (프레임 내부 은은한 테두리)
|
||
// ════════════════════════════════════════════════════════
|
||
GameObject innerLine = CreateUIObject("InnerLine", root.transform); // 생성할거에요 -> 안쪽 장식 라인을
|
||
Image innerLineImg = innerLine.AddComponent<Image>(); // 추가할거에요 -> Image를
|
||
innerLineImg.color = COL_FRAME_INNER; // 설정할거에요 -> 바랜 갈색 라인을
|
||
|
||
RectTransform innerLineRect = innerLine.GetComponent<RectTransform>(); // 가져올거에요 -> 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>(); // 추가할거에요 -> Image를
|
||
leftDecoImg.color = COL_DECO_LINE; // 설정할거에요 -> 은은한 갈색을
|
||
|
||
RectTransform leftDecoRect = leftDeco.GetComponent<RectTransform>(); // 가져올거에요 -> 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<TextMeshProUGUI>(); // 추가할거에요 -> 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>(); // 가져올거에요 -> 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>(); // 추가할거에요 -> Image를
|
||
barBgImg.color = COL_BAR_BG; // 설정할거에요 -> 짙은 검정 배경을
|
||
|
||
RectTransform barBgRect = barBg.GetComponent<RectTransform>(); // 가져올거에요 -> 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>(); // 추가할거에요 -> 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<RectTransform>()); // 실행할거에요 -> 부모에 스트레치
|
||
|
||
// ════════════════════════════════════════════════════════
|
||
// 10단계: HP 바 (어두운 붉은색, 실제 HP)
|
||
// ════════════════════════════════════════════════════════
|
||
GameObject hpFill = CreateUIObject("HP_Fill", barBg.transform); // 생성할거에요 -> HP 바를
|
||
Image hpFillImg = hpFill.AddComponent<Image>(); // 추가할거에요 -> 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<RectTransform>()); // 실행할거에요 -> 부모에 스트레치
|
||
|
||
// ════════════════════════════════════════════════════════
|
||
// 11단계: HP 바 위 그라디언트 하이라이트 (위쪽 밝은 선)
|
||
// ════════════════════════════════════════════════════════
|
||
GameObject highlight = CreateUIObject("BarHighlight", barBg.transform); // 생성할거에요 -> 하이라이트를
|
||
Image highlightImg = highlight.AddComponent<Image>(); // 추가할거에요 -> Image를
|
||
highlightImg.color = new Color(1f, 1f, 1f, 0.06f); // 설정할거에요 -> 아주 연한 흰색을 (은은한 광택)
|
||
|
||
RectTransform highlightRect = highlight.GetComponent<RectTransform>(); // 가져올거에요 -> 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<TextMeshProUGUI>(); // 추가할거에요 -> 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>(); // 가져올거에요 -> RectTransform을
|
||
SetStretch(hpTextRect); // 실행할거에요 -> 부모에 스트레치
|
||
hpTextRect.offsetMax = new Vector2(-6f, 0f); // 설정할거에요 -> 우측에 6px 여백을
|
||
|
||
// ════════════════════════════════════════════════════════
|
||
// 15단계: 페이즈 텍스트 (이름 아래 작게)
|
||
// ════════════════════════════════════════════════════════
|
||
GameObject phaseObj = CreateUIObject("Phase_Text", root.transform); // 생성할거에요 -> 페이즈 텍스트를
|
||
TextMeshProUGUI phaseTmp = phaseObj.AddComponent<TextMeshProUGUI>(); // 추가할거에요 -> 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>(); // 가져올거에요 -> 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>(); // 추가할거에요 -> 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<RectTransform>(); // 연결할거에요 -> Phase2 구분선을
|
||
so.FindProperty("phase3Divider").objectReferenceValue = phase3Div.GetComponent<RectTransform>(); // 연결할거에요 -> 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를 연결해주세요."); // 로그를 찍을거에요
|
||
}
|
||
|
||
// ─────────────────────────────────────────────────────────────
|
||
// 유틸리티 헬퍼 함수들
|
||
// ─────────────────────────────────────────────────────────────
|
||
|
||
/// <summary>RectTransform 포함 빈 UI 오브젝트 생성</summary>
|
||
private static GameObject CreateUIObject(string name, Transform parent) // 헬퍼를 정의할거에요 -> UI 오브젝트 생성용
|
||
{
|
||
GameObject obj = new GameObject(name); // 생성할거에요 -> 오브젝트를
|
||
obj.transform.SetParent(parent, false); // 설정할거에요 -> 부모를
|
||
if (obj.GetComponent<RectTransform>() == null) // 조건이 맞으면 실행할거에요 -> RectTransform 없으면
|
||
obj.AddComponent<RectTransform>(); // 추가할거에요 -> RectTransform을
|
||
return obj; // 반환할거에요 -> 오브젝트를
|
||
}
|
||
|
||
/// <summary>RectTransform을 부모에 꽉 차게 스트레치</summary>
|
||
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; // 설정할거에요 -> 여백 없음
|
||
}
|
||
|
||
/// <summary>페이즈 구분선 — 앵커 비율 기반 배치, 다크 판타지 색상</summary>
|
||
private static GameObject CreatePhaseDivider(string name, Transform parent, float ratio) // 헬퍼를 정의할거에요 -> 구분선 생성용
|
||
{
|
||
GameObject divider = CreateUIObject(name, parent); // 생성할거에요 -> 구분선 오브젝트를
|
||
Image divImg = divider.AddComponent<Image>(); // 추가할거에요 -> Image를
|
||
divImg.color = COL_DIVIDER; // 설정할거에요 -> 어두운 금색 반투명을
|
||
|
||
RectTransform divRect = divider.GetComponent<RectTransform>(); // 가져올거에요 -> 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; // 반환할거에요 -> 구분선을
|
||
}
|
||
}
|