wan의 개발일기

RoomCraft #8. 그리드 스냅 + 치수 표시 — 정렬 도우미와 가구 정보 UI 본문

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

RoomCraft #8. 그리드 스냅 + 치수 표시 — 정렬 도우미와 가구 정보 UI

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

들어가며

가구를 드래그로 배치할 수 있게 됐는데, 두 가지가 불편했다.

  • 가구를 정렬하고 싶은데 눈대중으로 맞춰야 해서 삐뚤삐뚤
  • 가구를 선택했을 때 이게 뭔지, 몇 cm인지 바로 안 보임

이번에는 그리드 스냅(10cm 단위로 딱딱 정렬)과 치수 표시(선택한 가구의 이름/크기/위치를 하단에 표시)를 추가한다.


그리드 스냅

뭘 하는 건가

그리드 스냅이 ON이면 가구를 드래그할 때 10cm(0.1m) 간격으로 끊어져서 움직인다. 가구끼리 나란히 정렬할 때 편하다. OFF면 자유롭게 부드러운 이동.

G키를 누르면 ON/OFF가 토글된다.

구현

원리는 간단하다. 위치값을 그리드 간격으로 나누고, 반올림하고, 다시 곱하면 된다.

public Vector3 Snap(Vector3 position)
{
    if (!snapEnabled)
        return position;

    float x = Mathf.Round(position.x / gridSize) * gridSize;
    float z = Mathf.Round(position.z / gridSize) * gridSize;

    return new Vector3(x, position.y, z);
}
예를 들어 gridSize가 0.1이고 position.x가 0.37이면: 0.37 / 0.1 = 3.7 → Round = 4 → 4 * 0.1 = 0.4. 즉 가장 가까운 10cm 지점으로 스냅된다.

이걸 HandleDrag()에서 MoveTo() 전에 호출하면 된다.

// 바닥에 Raycast로 얻은 위치
Vector3 targetPos = hit.point;

// 그리드 스냅 적용
GridSnap grid = FindAnyObjectByType<GridSnap>();
if (grid != null)
    targetPos = grid.Snap(targetPos);

selectedFurniture.MoveTo(targetPos);

치수 표시 (DimensionDisplay)

뭘 하는 건가

가구를 클릭해서 선택하면 화면 하단에 이름, 치수(cm), 현재 위치가 표시된다. 선택 해제하면 사라진다.

가구 선택 시 하단에 이름 / 치수 / 위치 표시

구현

매 프레임 interaction.GetSelectedFurniture()를 확인해서, 선택된 가구가 있으면 정보를 표시하고 없으면 숨긴다.

private void Update()
{
    FurnitureObject selected = interaction.GetSelectedFurniture();

    if (selected != null)
        ShowInfo(selected);
    else
        HidePanel();
}

private void ShowInfo(FurnitureObject furniture)
{
    panel.SetActive(true);

    FurnitureData data = furniture.GetData();
    nameText.text = data.furnitureName;
    sizeText.text = $"{data.widthCm} x {data.depthCm} x {data.heightCm} cm";

    Vector3 pos = furniture.transform.position;
    posText.text = $"위치: ({pos.x:F2}, {pos.z:F2})";
}

삽질 기록

스냅 결과를 안 쓰고 원본 위치를 넘김

grid.Snap()의 결과를 targetPos에 저장해놓고, 정작 MoveTo()에는 원본 hit.point를 넘기고 있었다. 스냅이 안 먹혀서 한참 헤맸다.

교훈: 변수 만들어놓고 안 쓰는 실수. 코드 리뷰 때 한 줄씩 따라가봐야 잡히는 류의 버그.

DimensionPanel을 SetActive(false)하면 스크립트도 멈춤

DimensionDisplay 스크립트를 패널 자체에 붙이고 panel.SetActive(false)로 숨겼더니, Update()가 멈춰서 다시 켜줄 수가 없었다.

해결: 스크립트를 항상 활성화 상태인 Canvas에 붙이고, 패널만 켜고 끄는 방식으로 변경.

정리

기능핵심 구현
그리드 스냅Mathf.Round(pos / gridSize) * gridSize
스냅 토글G키 → GridSnap.ToggleSnap()
치수 표시DimensionDisplay — 매 프레임 선택 가구 체크
패널 숨김panel.SetActive(false) (스크립트는 Canvas에 부착)

다음 편에서는 방 크기를 사용자가 직접 입력할 수 있는 UI를 만들 예정이다.