https://workdiarysometimesnot.tistory.com/126
랜덤 맵 생성] 1. 횡스크롤 수평 랜덤맵 생성하기
구현 목표 리스트1920 * 1080을 기준으로 16 : 9 비율의 화면에서 수평적인 랜덤 맵을 생성한다.수평칸 내에서 생성되는 방은 (맵 내의 분리된 개별 공간을 ‘방’이라고 명명) 서로 떨어져 있다.수
workdiarysometimesnot.tistory.com
이전 포스팅에서 디버그 및 오브젝트로 맵을 시각화 하였다.
1920*1080 사이즈의 월드에서 ground를 오브젝트로 인스턴스 하였는데
씬뷰가 1920 * 1080이라면 실제 월드는 그보다 더 큰 사이즈 일것이다.
또한 땅만 있는것이 아니라 tilemap을 사용하여 땅, 벽, 천장, 배경이 있는 방을 구현하고자 한다.
구현목록
- 맵 사이즈를 변동적으로 바꿀수 있게 설정
- 타일맵으로 맵 구현하기
1. 맵사이즈 변동적으로 적용하기
private void SetWorldArea()
{
_gridSizePixelX = _mapSizePixel.x / _gridColums;
_gridSizePixelY = _mapSizePixel.y / _gridLows;
// 한 칸의 좌표 구하기
_mapBottomLeft = _cam.ViewportToWorldPoint(new Vector3(0, 0, Mathf.Abs(_cam.transform.position.z))); // 좌측하단
_mapTopRight = _cam.ViewportToWorldPoint(new Vector3(1, 1, Mathf.Abs(_cam.transform.position.z))); // 우측상단
_mapBottomLeft.z = 0;
_mapTopRight.z = 0;
// 한 칸의 사이즈 구하기
float cellWidth = Mathf.Abs(_mapTopRight.x - _mapBottomLeft.x);
float cellHeight = Mathf.Abs(_mapTopRight.y - _mapBottomLeft.y);
// 월드의 전체 영역 사이즈 구하기
float worldWidth = cellWidth * _gridColums;
float worldHeight = cellHeight * _gridLows;
// 홀수는 가운데, 짝수는 절반 값 위치로 중앙 설정하여 top 계산
float yOffset = (_gridLows % 2 == 0) ? (cellHeight * 0.5f) : 0;
float worldTopLeftY = _mapTopRight.y + (Mathf.FloorToInt(_gridLows / 2) * (cellHeight + yOffset));
// 월드 전체 영역의 가운데 좌표
Vector3 worldCenter = new Vector3(
_mapBottomLeft.x + (worldWidth * 0.5f),
worldTopLeftY - (worldHeight * 0.5f),
0);
// 월드의 좌측하단, 우측상단 재설정
_mapBottomLeft = worldCenter - new Vector3(worldWidth, worldHeight, 0) * 0.5f;
_mapTopRight = worldCenter + new Vector3(worldWidth, worldHeight, 0) * 0.5f;
_mapSizeWorldMin = new Vector2(cellWidth, cellHeight);
}
mapSize : 맵사이즈 크기를 입력 (pixel)
gridColums, gridLows : 맵을 분할할 행열 개
적용하면 이렇게 큰 사이즈의 맵을 그리드로 분할할수있다.
빨간 라인으로 나눠진 한칸의 사이즈가 scene의 screen 사이즈다.
2. 타일맵으로 맵 구현하기
미리 찍는 타일맵이 아니라 랜덤방을 런타임중에 생성하려고함
// set tilemap
private void TilingMap()
{
Vector2 oneTileSize = new Vector2(_mapSizeWorldMin.x / GRID_WIDTH, _mapSizeWorldMin.y / GRID_HEIGHT);
foreach (var level in levels)
{
foreach (var node in level.Value)
{
GameObject mapInstanced = Instantiate(_groundOBJ.gameObject);
SimpleGround ground = mapInstanced.GetComponent<SimpleGround>();
if (ground == null)
{
return;
}
// background
float x = _mapBottomLeft.x + (node.x * _mapSizeWorldMin.x);
float y = _mapBottomLeft.y + (node.y * _mapSizeWorldMin.y);
_tileMapController.SetTileArea(MapTile.Background, new Vector3(x, y, _mapBottomLeft.z), node.length * GRID_WIDTH, GRID_HEIGHT);
// wall
_tileMapController.SetTileArea(MapTile.WallLeft, new Vector3(x, y, _mapBottomLeft.z), 1, GRID_HEIGHT);
x += node.length * _mapSizeWorldMin.x - oneTileSize.x;
_tileMapController.SetTileArea(MapTile.WallRight, new Vector3(x, y, _mapBottomLeft.z), 1, GRID_HEIGHT);
// ceiling
x = _mapBottomLeft.x + (node.x * _mapSizeWorldMin.x);
y += _mapSizeWorldMin.y - oneTileSize.y;
_tileMapController.SetTileArea(MapTile.Ceiling, new Vector3(x, y, _mapBottomLeft.z), node.length * GRID_WIDTH, 1);
// ground
x = _mapBottomLeft.x + (node.x * _mapSizeWorldMin.x);
y = _mapBottomLeft.y + (node.y * _mapSizeWorldMin.y);
_tileMapController.SetTileArea(MapTile.Ground, new Vector3(x, y, _mapBottomLeft.z), node.length * GRID_WIDTH, 1);
}
}
}
grid가 맞춰진 이후 바닥, 벽, 천장, 배경을 나눠 tile을 만들어주었다
구현된 모습
타일맵이 유니티의 기본 grid를 기준으로 생성되기 때문에 내 카메라 설정의 screen영역과 정확하게 grid가 일치하지 않는 경우가 생겼다.
따로 해당 이슈를 해결한 트러블슈팅 정리 문서를 첨부한다.
'공부' 카테고리의 다른 글
Cursor ai with figma (0) | 2025.04.20 |
---|---|
랜덤 맵 생성] 트러블슈팅! screen 화면과 tilemap grid 화면이 맞지않음 (0) | 2025.02.20 |
랜덤 맵 생성] 1. 횡스크롤 수평 랜덤맵 생성하기 (0) | 2025.02.09 |
Unity내의 병렬적 작업 처리와 유사 개념 정리 (0) | 2025.02.04 |
[TIL] 250111 Dependency Injection 개념 공부 (0) | 2025.02.04 |
댓글