wan의 개발일기
RoomCraft 개발일지 #4. 충돌 감지 — 벽 밖 제한 + 겹침 경고 본문
소스코드 → github.com/Jywan/RoomCraft
들어가며
지난 편에서 가구를 드래그로 움직이는 건 됐는데, 벽 밖으로 나가거나 가구끼리 겹치는 게 가능했다. 실제로 가구를 배치할 때 이러면 안 되니까, 이번에는 충돌 감지를 추가한다.
구현할 기능:
- 가구가 방 범위를 벗어나면 빨간색 경고
- 다른 가구와 겹치면 빨간색 경고
- 마우스를 떼는 순간 무효한 위치면 마지막 유효 위치로 자동 복귀
경계 검사 설계
방의 크기를 알고 있으니까, 가구의 Collider bounds가 방 범위를 벗어나는지 계산하면 된다.
방의 중심이 (0, 0, 0)이고 크기가 4m × 3m이면, X축으로 -2 ~ +2, Z축으로 -1.5 ~ +1.5가 유효 범위다. 가구의 bounds.min/max가 이 범위를 넘으면 밖으로 나간 거.
FurnitureBounds 구현
방 경계 검사
public bool IsInsideRoom(FurnitureObject furniture)
{
Bounds bounds = furniture.GetComponent<Collider>().bounds;
float halfWidth = roomWidth / 2f;
float halfDepth = roomDepth / 2f;
// 가구의 경계가 방 범위를 벗어나는지 체크
if (bounds.min.x < -halfWidth || bounds.max.x > halfWidth)
return false;
if (bounds.min.z < -halfDepth || bounds.max.z > halfDepth)
return false;
return true;
}
Collider.bounds는 월드 좌표 기준으로 오브젝트가 차지하는 영역을 반환한다. 회전해도 제대로 계산해주니까 따로 회전 처리를 할 필요가 없다.
가구 겹침 검사
public bool IsOverlapping(FurnitureObject furniture)
{
Bounds myBounds = furniture.GetComponent<Collider>().bounds;
FurnitureObject[] allFurniture = FindObjectsByType<FurnitureObject>(FindObjectsSortMode.None);
foreach (FurnitureObject other in allFurniture)
{
if (other == furniture) continue; // 자기 자신은 스킵
Bounds otherBounds = other.GetComponent<Collider>().bounds;
if (myBounds.Intersects(otherBounds))
return true;
}
return false;
}
Bounds.Intersects()가 두 경계 상자가 겹치는지 한 줄로 알려준다. 가구 수가 적으니 성능 문제는 없다.
종합 검증 + 시각 피드백
public bool ValidatePosition(FurnitureObject furniture)
{
bool insideRoom = IsInsideRoom(furniture);
bool overlapping = IsOverlapping(furniture);
Renderer renderer = furniture.GetComponent<Renderer>();
if (!insideRoom || overlapping)
{
// 빨간색 경고
renderer.material.color = warningColor;
return false;
}
else
{
// 정상: 선택 색으로 복귀
furniture.Select();
return true;
}
}
드래그에 연동
기존 HandleDrag()를 수정해서, 드래그 중에 매 프레임 ValidatePosition()을 호출한다.
private void HandleDrag()
{
if (selectedFurniture == null || !isDragging) return;
if (Input.GetMouseButtonUp(0))
{
isDragging = false;
// 최종 위치가 무효하면 마지막 유효 위치로 복귀
if (bounds != null && !bounds.ValidatePosition(selectedFurniture))
{
selectedFurniture.MoveTo(lastValidPosition);
selectedFurniture.Select();
}
return;
}
Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100f, floorLayer))
{
selectedFurniture.MoveTo(hit.point);
// 드래그 중 실시간 검증
if (bounds != null)
{
bool valid = bounds.ValidatePosition(selectedFurniture);
if (valid)
lastValidPosition = hit.point;
}
}
}
핵심은 “드래그 중에는 경고만 보여주고, 마우스를 뗐을 때 비로소 복귀시킨다”는 점이다. 드래그 도중에 강제로 못 가게 막으면 UX가 답답해진다.
실행 결과
마우스를 떼면 빨간색이었던 가구가 자동으로 마지막 유효 위치로 돌아간다.
정리
| 기능 | 핵심 구현 |
|---|---|
| 방 경계 검사 | Collider.bounds의 min/max를 방 크기와 비교 |
| 겹침 검사 | Bounds.Intersects()로 다른 가구와 교차 여부 판단 |
| 시각 피드백 | 무효 위치면 빨간색, 유효면 선택 색으로 복귀 |
| 자동 복귀 | 마우스 업 시 무효 → lastValidPosition으로 이동 |
다음 편에서는 사용자가 직접 카테고리/치수/색상을 선택해서 가구를 만드는 UI를 구현할 예정이다.
'1인 게임개발 활동 > 가구배치 시뮬레이터' 카테고리의 다른 글
| RoomCraft #6. 카테고리별 동적 모델 생성 — 팩토리 패턴으로 가구 형태 조합 (0) | 2026.06.28 |
|---|---|
| RoomCraft #5. 가구 생성 UI — 카테고리/치수/색상 입력 팝업 (0) | 2026.06.28 |
| RoomCraft 개발일지 #3. 가구 드래그 앤 드롭 — 선택, 이동, 회전, 삭제 (0) | 2026.06.26 |
| RoomCraft 개발일지 #2. 카메라 시스템 — 탑뷰 ↔ 3D 뷰 전환 (0) | 2026.06.25 |
| RoomCraft 개발일지 #1 — 프로젝트 설정 + 방 생성 시스템 (0) | 2026.06.25 |