2D에서 랜덤 좌표 x,y를 타일맵에서 가져오기 위한 고민
내가 오늘 하고 싶었던건 타일맵 위에 아이템을 랜덤으로 스폰하는 것이었다.
일반적인 타일맵은 직사각형 형태의 `x, y`가 명확한 형태이다.
그래서 그냥 타일맵의 `x, y`의 최소~최대값 사이의 랜덤값을 뽑으면 됐다.
그런데 위와 같은 아이소메트릭 형태의 타일맵은 그냥 x, y값을 가져와도 되는건가? 의문이었다.
생각해본 첫 번째 방법
2024.06.05 - [스파르타 게임개발종합반(Unity)/TIL - 본캠프 매일 공부 기록] - 2024.06.05 TIL - MenuItem, 유니티 메뉴창에 툴 구현하기
▲ 지난번에 오브젝트에 자동으로 박스 콜라이더를 부착하는 툴을 만든 적이 있다.
그때 사용했던 방식 중, 오브젝트의 스킨 랜더러의 `bounds`를 받아와 경계의 최소~최대값을 알 수 있었다.
그러면 `TileCollider2D`의 `bounds`를 받아오면 되지 않을까? 생각했다.
그런데 타일맵의 콜라이더는 그려야한다...!
그래서 자동으로 바닥의 콜라이더를 그려주는 툴을 만드려고 했다.
그런데 이게 이렇게 복잡해질 일인가? 더 쉬운 방법은 없을까? 고민했다.
생각해본 두 번째 방법
파란색 동그라미가 꼭짓점으로 된 네모 영역안이 타일맵이다.
`Tilemap`이 위의 그림에서 네모 영역이고, `Tilemap Renderer`가 그려진 초록색 타일맵영역이다.
내가 원하는건 초록색 영역이니까 `Tilemap Renederer`의 `bounds`를 받아오면 되지 않을까?
아.. 그런거 없음~ ㅋㅋ
이리저리 찾아보니 타일맵 안의 타일들 정보를 알고 있는건 `Tilemap`이고, `Tilemap Renderer`는 타일 정보를 가지고 있지 않다.
그래서 `Tilemap`안의 타일들을 검사해서 존재하는 타일(초록색 타일)인지 확인하고, 해당 타일의 좌표값을 받아오면 됐다!
public Tilemap SpawnRange;
private List<Vector3Int> validTilePositions = new List<Vector3Int>();
private void FindValidTilePositions()
{
BoundsInt bounds = SpawnRange.cellBounds;
for (int x = bounds.xMin; x < bounds.xMax; x++)
{
for (int y = bounds.yMin; y < bounds.yMax; y++)
{
Vector3Int tilePosition = new Vector3Int(x, y, 0);
if (SpawnRange.HasTile(tilePosition))
{
validTilePositions.Add(tilePosition);
}
}
}
}
타일맵 영역 == `SpawnRange`
타일맵 한 칸 == `SpawnRange.cellBounds`
`2D`인데 왜 `Vector3`인거지? 의문이었는데, 타일의 위치를 `Vector3Int`로 표현한다고 한다.
일반적인 직사각형 타일맵이었으면 `Vector2`로 해도 될 것 같은데, 아이소 매트릭이다보니 정확한 `x, y`좌표가 필요해서인 것 같다.
`SpawnRange.HasTile`을 통해 타일이 있는지 검사할 수 있다.
`FindValidTilePositions()`는 `Start()`에서 미리 유효한 타일 검사를 해뒀다.
스폰할 때마다 검사하면 비용이 낭비된다고 생각했다.
그래서 미리 검사한 후 유효한 타일의 위치들을 리스트에 담아뒀다.
private Vector3 ReturnRandPos()
{
Vector3 randomPos = Vector3.zero;
if (validTilePositions.Count > 0)
{
Vector3Int randomTilePos = validTilePositions[Random.Range(0, validTilePositions.Count)];
randomPos = SpawnRange.CellToWorld(randomTilePos);
}
return randomPos;
}
리스트에 담아둔 위치에서 랜덤 좌표를 뽑아오는데 주의할 점이 있다.
`SpawnRange.CellToWorld`를 통해 타일 좌표를 월드 좌표로 변환해줘야 한다.
이유는 타일맵에서는 각 타일이 그리드 상에 위치하며, 이 위치를 타일 좌표로 표현하기 때문이다.
월드에 있는 타일 좌표를 알아야하기 때문에 월드 좌표로 변환하는 것이다.
'스파르타 게임개발종합반(Unity) > TIL - 본캠프 매일 공부 기록' 카테고리의 다른 글
2024.06.24 TIL - Photon Pun2 (0) | 2024.06.24 |
---|---|
2024.06.21 TIL - 이벤트 구독 취소의 중요성 (0) | 2024.06.21 |
2024.06.19 TIL - 기초적인 네트워크 지식 (0) | 2024.06.19 |
2024.06.18 TIL - 코루틴(Coroutine) (0) | 2024.06.18 |
2024.06.17 TIL - switch문, switch식, Func (0) | 2024.06.17 |
댓글