wan의 개발일기
RoomCraft #15. 방 모양 프리셋 — 사각형 넘어 L자형까지 본문
소스코드 → github.com/Jywan/RoomCraft
들어가며
지난 편에서 방을 다각형 기반으로 재구성했다. 겉으로는 사각형 방이 예전과 똑같이 나왔지만, 속은 "꼭짓점 리스트 하나만 던져주면 어떤 모양이든 만들어주는" 구조로 바뀌어 있었다. 이번 편은 그 구조 위에 실제로 L자형을 골라 쓸 수 있는 UI를 얹었다. 드디어 사각형이 아닌 방이 화면에 나온다.
방 모양 프리셋
모양 하나마다 "가로/세로를 받아서 꼭짓점을 어떻게 배치할지"만 정의하면 된다. 사각형은 원래 있던 대로, L자형은 우측 상단 사분면을 절반씩 잘라낸 6꼭짓점으로 만들었다.
public static List<Vector2> GetVertices(RoomShape shape, float width, float depth)
{
switch (shape)
{
case RoomShape.LShape:
return LShapeVertices(width, depth);
default:
return RectangleVertices(width, depth);
}
}
// 우측 상단 사분면을 잘라낸 L자형 (6꼭짓점)
private static List<Vector2> LShapeVertices(float width, float depth)
{
float halfW = width / 2f;
float halfD = depth / 2f;
return new List<Vector2>
{
new Vector2(-halfW, -halfD),
new Vector2(halfW, -halfD),
new Vector2(halfW, 0f),
new Vector2(0f, 0f),
new Vector2(0f, halfD),
new Vector2(-halfW, halfD),
};
}
이 리스트를 지난 편에 만든 RoomBuilder에 그대로 넘기면, 삼각분할이랑 벽 생성이 알아서 6개짜리 다각형에 맞춰 동작한다. 새로 만든 모양 하나 추가하는데 RoomBuilder 쪽은 한 줄도 안 건드렸다 — 지난 편에서 구조를 미리 바꿔둔 보람이 여기서 나왔다.
새 프로젝트 화면에 모양 선택 Dropdown을 추가하고, 선택한 값을 SessionData에 담아 EditorScene으로 넘겼다.
경계 검사도 다각형 기준으로
모양을 실제로 노출하려니 미뤄뒀던 문제가 튀어나왔다. 가구가 방 밖으로 나갔는지 검사하는 FurnitureBounds가 아직도 사각형 바운딩 박스로만 검사하고 있었다 — 이대로면 L자형의 파인 부분에도 가구를 놓을 수 있게 된다. 눈으로는 L자인데 판정은 사각형인 셈.
점이 다각형 안에 있는지 판정하는 Ray Casting 알고리즘을 추가하고, 가구의 바운딩 박스 네 모서리가 전부 다각형 안에 있어야 유효하다고 판정하도록 바꿨다.
public static bool PointInPolygon(Vector2 point, List<Vector2> polygon)
{
bool inside = false;
int n = polygon.Count;
for (int i = 0, j = n - 1; i < n; j = i++)
{
Vector2 pi = polygon[i];
Vector2 pj = polygon[j];
bool intersects = ((pi.y > point.y) != (pj.y > point.y)) &&
(point.x < (pj.x - pi.x) * (point.y - pi.y) / (pj.y - pi.y) + pi.x);
if (intersects)
inside = !inside;
}
return inside;
}
"점에서 오른쪽으로 반직선을 그었을 때 다각형 변과 홀수 번 만나면 내부, 짝수 번 만나면 외부"라는 원리다. 벽 두께 보정도 사각형일 땐 그냥 가로/세로 절반에서 빼면 됐는데, 다각형은 그렇게 간단히 안 돼서 중심점 기준으로 각 꼭짓점을 살짝 안쪽으로 당기는 방식으로 근사했다.
삽질 기록
드롭다운 목록만 한글이 깨짐
Dropdown을 새로 만들고 옵션을 한글로 넣었는데, 접혀있을 때 보이는 글자는 멀쩡한데 펼쳤을 때 나오는 목록 글자만 깨져 나왔다. TMP Dropdown은 평소 보이는 라벨이랑 펼침 목록(Template)의 텍스트가 서로 다른 컴포넌트라, 목록 쪽(Item Label)이 한글 미지원 기본 폰트를 그대로 쓰고 있었던 것.
해결: Template → Viewport → Content → Item → Item Label까지 들어가서 폰트를 프로젝트에서 쓰는 한글 폰트로 교체.
메서드는 만들어놓고 호출을 안 함
Dropdown 옵션을 코드로 채워 넣는 SetupShapeDropdown()을 작성해놓고, Start()에서 호출하는 걸 깜빡했다. 그래서 Play 모드에서도 계속 Unity 기본 템플릿 옵션(Option A/B/C)이 나왔다 — 코드 리뷰할 때 함수 본문만 보고 "잘 짰네" 하고 넘어갔는데, 실제로 불려지는지까지 확인했어야 했다.
null 체크 방향이 반대로 됨
FurnitureBounds.IsInsideRoom()에 "방 모양 정보가 아직 없으면 일단 유효하다고 봐준다"는 안전장치를 넣으려다가, true 대신 false를 반환하게 잘못 타이핑했다. 이러면 정보가 없는 동안 모든 가구가 무조건 경계 밖으로 판정된다 — 의도랑 정반대인 코드.
다행히 실제 플레이 흐름에서는 방 생성 직후 바로 값이 채워져서 눈에 띄는 증상은 없었지만, 나중에 타이밍이 조금만 달라져도 바로 터질 수 있는 코드였다.
정리
| 기능 | 핵심 API / 구조 |
|---|---|
| 방 모양 프리셋 | RoomShape enum + RoomShapePresets.GetVertices() |
| 다각형 내부 판정 | PolygonUtils.PointInPolygon() — Ray Casting |
| 다각형 기준 경계 검사 | FurnitureBounds.SetRoomShape() + 바운딩 박스 네 모서리 판정 |
| 모양 선택 UI | StartSceneUI의 ShapeDropdown → SessionData → EditorSceneLoader |
| 다음 단계 | Phase 5-3(커스텀 편집)은 그리드 셀 선택 방식으로 진행 예정 |
'1인 게임개발 활동 > 가구배치 시뮬레이터' 카테고리의 다른 글
| RoomCraft #17. 매 프레임 도는 코드 최적화하기 — 그리고 최적화하다 만든 버그 (0) | 2026.07.08 |
|---|---|
| RoomCraft #16. 방 모양 편집을 일반/커스텀 탭으로 - 그리고 버그 네 마리 (0) | 2026.07.07 |
| RoomCraft #14. 방을 다각형으로 - 사각형을 넘어서기 위한 첫걸음 (0) | 2026.07.05 |
| RoomCraft #13. 버그 두 개 잡고 가구 정보 패널 통합하기 (0) | 2026.07.05 |
| RoomCraft #12. 룸/가구 툴바 분리 + 색상 피커 만들기 (0) | 2026.07.05 |