728x90
■ 벽 생성
이제 BSP 알고리즘으로 생성한 던전에 벽을 배치하여 마무리한다.
벽은 Mesh를 사용해서 통으로 생성하는 것이 아니라, 벽 오브젝트를 1 유닛 단위로 배치하여 맵 전체를 감싸는 방식으로 구현한다.
■ 상세 구현
벽 생성 로직 자체는 비교적 단순하다.
각 방의 좌하단→우하단(수평), 좌하단 → 좌상단(수직) 방향으로 1씩 좌표를 증가시키며, 벽을 배치할 좌표를 저장한다.
- 동일하게 반대 방향(좌상단→ 우상단(수평), 우하단 → 우상단(수직)) 방향도 기록한다.
- 좌표 기록은 바닥 Mesh를 생성할 때 같이 진행한다.
단, 복도와 겹치는 구간에는 벽을 생성하면 안 된다.
따라서 벽을 배치할 좌표를 저장할 때, 이미 기록된 좌표가 넘어온다면 복도와 겹치는 공간이므로 저장된 좌표를 삭제한다.
public class MeshGenerator : MonoBehaviour
{
private static HashSet<Vector3Int> _wallHorizontal = new HashSet<Vector3Int>();
private static HashSet<Vector3Int> _wallVertical = new HashSet<Vector3Int>();
public void CreateMesh(NodePosition position)
{
// 기존 mesh 생성 코드 생략
for (var col = position.BL.x; col < position.BR.x; ++col)
{
var pos = new Vector3Int(col, 0, position.BL.y);
AddWallPosition(pos, ELine.Horizontal);
}
for (var col = position.TL.x; col < position.TR.x; ++col)
{
var pos = new Vector3Int(col, 0, position.TL.y);
AddWallPosition(pos, ELine.Horizontal);
}
for (var row = position.BL.y; row < position.TL.y; row++)
{
var pos = new Vector3Int(position.BL.x, 0, row);
AddWallPosition(pos, ELine.Vertical);
}
for (var row = position.BR.y; row < position.TR.y; row++)
{
var pos = new Vector3Int(position.BR.x, 0, row);
AddWallPosition(pos, ELine.Vertical);
}
}
]
[MeshGenerator.cs]
HashSet<>을 사용하여 중복된 좌표(복도와 겹치는 부분)가 저장되지 않도록 처리하였다.
각 방의 외곽을 기준으로, 수평(x 증가)과 수직(y 증가)을 따라 1씩 좌표를 증가시키며 벽 좌표를 기록한다.
- 수평 벽 : BL→ BR, TL → TR 경계를 따라 좌표를 저장한다.
- 수직 벽 : BL→ TL, BR → TR 경계를 따라 좌표를 저장한다.
public void CreateWall()
{
foreach (var pos in _wallHorizontal)
{
Instantiate(horizontalWall, pos, horizontalWall.transform.rotation, transform);
}
foreach (var pos in _wallVertical)
{
Instantiate(verticalWall, pos, verticalWall.transform.rotation, transform);
}
_wallHorizontal.Clear();
_wallVertical.Clear();
}
private void AddWallPosition(Vector3Int pos, ELine dir)
{
switch (dir)
{
case ELine.Horizontal:
if (_wallHorizontal.Add(pos) == false)
_wallHorizontal.Remove(pos);
break;
case ELine.Vertical:
if (_wallVertical.Add(pos) == false)
_wallVertical.Remove(pos);
break;
case ELine.None:
default:
return;
}
}
[MeshGenerator.cs]
Add()의 결과가 false일 경우, 복도와 겹치는 부분이므로 해당 좌표를 삭제하여 벽이 생성되지 않도록 한다.
- 이렇게 기록된 좌표를 기반으로 CreateWall()에서 실제 벽 오브젝트를 배치하여 마무리한다.
■ 최종 결과
728x90
'Unity,C# > 절차적생성(PCG)' 카테고리의 다른 글
[C#, Unity, 절차적 생성] 절차적 던전 생성 - 4. 복도 생성 (1) | 2025.05.21 |
---|---|
[C#, Unity, 절차적 생성] 절차적 던전 생성 - 3. BSP 알고리즘 개선 (1) | 2025.05.12 |
[C#, Unity, 절차적 생성] 절차적 던전 생성 - 2. 방 생성 (0) | 2025.05.12 |
[C#, Unity, 절차적 생성] 절차적 던전 생성 - 1. Binary Space Partitioning (1) | 2025.05.07 |
[C#, Unity, 절차적 생성] 절차적 지형 생성 - 3.터레인 생성 (0) | 2025.04.28 |