게임에서 자주 볼 수 있는 기능인데, 맞춰진 격자에 맞춰 물건을 배치할 수 있도록 규격을 제시하는 크래프팅 시스템을 만들고 싶었다.
우선 C++로 타일맵 시스템을 만들었던 기억을 되짚어보며 직접 계산할 방법을 떠올려보았다.
임의로 Grid 한 Cell의 크기를 설정하고, 마우스 포인터의 위치를 Cell 크기에 기반한 계산을 통해 몇번째 Cell인지 알아낼 수 있도록 하려고 했다. Cell의 Index를 구하면 [중심값 + Index.x * Cell 크기] 같은 식으로 중심의 point를 알 수 있다.
그런데 유니티에서 Cell의 Index 계산과 특정 Cell의 중심점의 World Position을 구하는 기능을 제공하는 컴포넌트가 있다.!! 바로 Grid이다. 유니티에서는 타일맵 에디터를 제공하는데, 그때 사용되는 Grid와 동일한 컴포넌트다.
Grid 사용해서 Building 시스템 만들기
규격을 제공하는 역할을 할 곳(ex: 바닥)에 Grid 컴포넌트를 붙여주고 Cell Size와 Cell 사이 간격을 설정할 수 있다.
위에 그림으로 그린 과정을 제공하는 Grid의 함수들이다.
- WorldToCell(Vector3 position): position에 해당하는 Cell 인덱스를 Vector3Int로 반환.
- GetCellCenterWorld(Vector3Int position): Cell 인덱스인 position의 중심점의 World 좌표를 반환.
코드
- Preview용 블록인 PrevireBlock 은 Update 함수에서 계속 마우스의 위치에 해당하는 Cell의 중심으로 위치를 고정해주고 있다.
- GetSelectedMapPosition은 마우스 위치에서 Ray를 쏘고, 건설 가능한 Layer("CanCreate")가 있다면 해당 RaycastHit의 point를 반환한다.
- 마우스 클릭이 발생하면 놓아야 하는 블록인 BlockToBuild를 PreviewBlock의 위치에 놓는다.
void Update()
{
Vector3 selectedPos = GetSelectedMapPosition(Input.mousePosition);
Vector3Int cell = grid.WorldToCell(selectedPos);
PreviewBlock.transform.position = grid.GetCellCenterWorld(cell);
if (Input.GetMouseButtonDown(0))
{
GameObject go = Instantiate(BlockToBuild, PreviewBlock.transform.position, Quaternion.identity);
go.layer = LayerMask.NameToLayer("CanCreate"); // 해결점 1
}
}
문제점 1
여기서 '// 해결점 1' 주석이 달린 라인의 코드를 보면, 물건을 놓는 순간 그 물건의 Layer를 건설 가능한 레이어로 바꿔놓는다. 이렇게 하지 않으면 계속 CanCreate Layer를 인식할 때 바닥만 인식되어서 1층짜리 건설밖에 할 수 없다.
GetSelectedMapPosition 코드
Vector3 GetSelectedMapPosition(Vector3 mousePos)
{
mousePos.z = Camera.nearClipPlane;
Ray ray = Camera.ScreenPointToRay(mousePos);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 100, CanCreateLayerMask))
{
lastSelectedPosition = hit.point;
}
return lastSelectedPosition;
}
문제점 2
높이 쌓은 기둥의 옆면에는 허공에 설치 가능하다. 앞면에도 설치가 되면 좋겠는데!! 안되는 모습이다.
예측 가설은, Grid의 경계면에 딱 맞춰 hit되었을 때 접하는 양쪽 면 중에 어느 Cell로 판단되는지 계산되는 부분에서 뒷쪽 셀을 선택하는 것이었다.
그래서!!!! Collider의 사이즈를 0.001씩 추가해서 조금 더 앞부분이 RaycastHit 될 수 있도록 변경했다!! 꼼수로 해결 굳.
실행하는 모습
'공부 기록 > 유니티 Unity' 카테고리의 다른 글
[Unity/TIL] 2D 최적화(2) - 드로우 콜 줄이기, 캔버스 중첩 (4) | 2025.04.07 |
---|---|
[Unity/TIL] 2D 최적화(1) - 사이즈 관련 (0) | 2025.04.04 |
[Unity/TIL] 인벤토리 / 아이템 구현, FSM, AI Navigation 복습 (1) | 2025.03.26 |
[Unity/TIL] UI에 바로 적용할 수 있는 기본 제공 이벤트 핸들러 (Hover, Exit, Down, Drag, ...) (0) | 2025.03.24 |
[Unity/TIL] 렌더링 파이프라인과 URP에 대하여 | 에셋이 분홍색으로 보이는 현상 (3) | 2025.03.21 |