wan의 개발일기

RoomCraft #5. 가구 생성 UI — 카테고리/치수/색상 입력 팝업 본문

1인 게임개발 활동/가구배치 시뮬레이터

RoomCraft #5. 가구 생성 UI — 카테고리/치수/색상 입력 팝업

wan_ 2026. 6. 28. 08:58
소스코드 → github.com/Jywan/RoomCraft

들어가며

지금까지는 코드에서 직접 new FurnitureData(...)로 가구를 만들었다. 근데 이건 테스트용이지 실제 사용 방식이 아니다.

이번에는 사용자가 직접 카테고리, 치수, 이름, 색상을 입력해서 가구를 생성하는 UI 팝업을 만든다.


UI 구조 설계

Unity의 uGUI(Canvas 기반)로 만들었다. 구조는 이렇다:

Canvas
├── AddFurnitureButton        ← "가구 추가" 버튼 (좌측 상단)
└── FurnitureCreatorPanel     ← 팝업 (중앙, 평소엔 숨김)
    ├── CategoryDropdown
    ├── NameInput
    ├── WidthInput
    ├── DepthInput
    ├── HeightInput
    ├── ColorPreview
    ├── ColorRow (가로 배치)
    │   └── ColorBtn_1~6
    └── ButtonRow (가로 배치)
        ├── CreateButton
        └── CancelButton
Panel 안에 Vertical Layout Group을 붙이면 자식 요소들이 위에서 아래로 자동 정렬된다. 색상 버튼은 Horizontal Layout Group으로 가로 배치.

한글 폰트 설정

TextMeshPro 기본 폰트는 한글을 지원하지 않는다. 한글 넣으면 네모(□)로 깨진다.

해결 방법

  1. Google Fonts에서 Noto Sans KR Static 버전 다운로드
  2. NotoSansKR-Regular.ttf를 Assets/Fonts에 넣기
  3. Window → TextMeshPro → Font Asset Creator
  4. Character Set: Unicode Range (Hex)
  5. Character Sequence: 20-7E,AC00-D7A3
  6. Generate Font Atlas → Save
AC00-D7A3이 한글 완성형 전체 범위(가~힣)다. 20-7E는 영문+숫자+기호. 이 두 범위를 같이 넣으면 한글/영문 모두 표시된다.

FurnitureCreatorUI 구현

핵심: 입력값 파싱 → 가구 생성

private void OnCreateClicked()
{
    string furnitureName = nameInput.text;
    if (string.IsNullOrEmpty(furnitureName))
        furnitureName = "이름없는 가구";

    float width, depth, height;
    if (!float.TryParse(widthInput.text, out width)) width = 50f;
    if (!float.TryParse(depthInput.text, out depth)) depth = 50f;
    if (!float.TryParse(heightInput.text, out height)) height = 50f;

    // 1cm ~ 500cm 제한
    width = Mathf.Clamp(width, 1f, 500f);
    depth = Mathf.Clamp(depth, 1f, 500f);
    height = Mathf.Clamp(height, 1f, 500f);

    FurnitureCategory category = (FurnitureCategory)categoryDropdown.value;

    FurnitureData data = new FurnitureData(furnitureName, category, width, depth, height);
    data.color = selectedColor;

    furnitureInteraction.CreateFurniture(data);
    panel.SetActive(false);
}

입력 안 하면 기본값 50cm로 들어가고, 1~500cm 범위를 벗어나면 클램핑된다. 잘못된 입력에 앱이 터지지 않게.

색상 선택

private void SetupColorButtons()
{
    foreach (Button btn in colorButtons)
    {
        Color btnColor = btn.GetComponent<Image>().color;
        btn.onClick.AddListener(() => SelectColor(btnColor));
    }
}

각 버튼의 Image 색상을 그대로 가져와서 선택 색으로 쓴다. 버튼 색 = 가구 색.


실행 결과

가구 생성 팝업 — 카테고리, 치수, 색상 선택
팝업에서 생성한 가구가 방 안에 배치된 모습

삽질 기록

TextMeshPro 한글 깨짐

처음에 Custom Characters로 글자를 하나하나 넣었는데, “카테”에서 “테”가 빠져서 깨졌다.

해결: Character Set을 Unicode Range (Hex)로 바꾸고 AC00-D7A3을 넣으면 한글 전체가 들어간다. 글자 하나하나 안 넣어도 됨.

UI 입력 중 게임 단축키 반응

이름 입력하다가 T를 누르면 카메라가 전환됐다. InputField에 포커스가 있어도 게임 키 입력이 동시에 먹히는 거였다.

해결: Update 맨 위에서 EventSystem.current.currentSelectedGameObject가 있으면 단축키를 무시하도록 처리.

가구 생성하면 기존 가구 사라짐

새 가구를 만들 때마다 기존에 있던 가구가 하나씩 사라졌다. 같은 위치에 Collider가 겹치면서 Unity 물리엔진이 오브젝트를 밀어내는 거였다.

해결: 가구 Collider를 isTrigger = true로 설정하고, Project Settings → Physics → Queries Hit Triggers 활성화. 물리 충돌은 안 일어나면서 Raycast는 감지됨.

정리

기능핵심 구현
생성 팝업FurnitureCreatorUI — 입력 파싱 + CreateFurniture() 호출
한글 폰트Unicode Range AC00-D7A3으로 Font Atlas 생성
색상 선택버튼 Image 색상을 AddListener로 캡처
입력 충돌 방지EventSystem.currentSelectedGameObject 체크
물리 충돌 방지isTrigger + Queries Hit Triggers

다음 편에서는 카테고리별로 다른 3D 형태(침대는 납작하게, 책상은 상판+다리 등)를 동적으로 생성하는 기능을 구현할 예정이다.