유니티 로그라이크 방 생성Unity/Study2023. 12. 15. 20:50
Table of Contents
기능 구현
GameScene.cs
public class GameScene : MonoBehaviour
{
#region Field
[SerializeField] private int roomAmount;
private Room _roomPrefab;
private Room[,] _roomArray = new Room[20, 20];
#endregion
#region Init
private void Start()
{
Main.Resource.Initialize();
// #1. 방 생성
_roomPrefab = Main.Resource.GetObject("Room").GetComponent<Room>();
CreateLevel();
// #2. 플레이어 생성
Main.Game.SpawnPlayer(this.transform);
}
#endregion
#region Room Method
/// <summary>
/// 던전 생성
/// </summary>
private void CreateLevel()
{
// 방 생성을 위한 좌표 리스트
List<Vector2Int> alternativeRoomList = new();
List<Vector2Int> hasBeenRemoveRoomList = new();
// 시작 방 생성
int outsetX = _roomArray.GetLength(0) / 2;
int outsetY = _roomArray.GetLength(1) / 2;
Room startRoom = _roomArray[outsetX, outsetY] = CreateRoom(new Vector2Int(outsetX, outsetY));
// 방 생성 델리게이트
Action<int, int> action = (newX, newY) =>
{
Vector2Int coordinate = new(newX, newY);
if (_roomArray[newX, newY] == null)
{
if (alternativeRoomList.Contains(coordinate))
{
alternativeRoomList.Remove(coordinate);
hasBeenRemoveRoomList.Add(coordinate);
}
else if (!hasBeenRemoveRoomList.Contains(coordinate))
{
alternativeRoomList.Add(coordinate);
}
}
};
// 지정된 수 만큼 방 생성
for (int i = 1; i < roomAmount; i++)
{
int x = startRoom.coordinate.x;
int y = startRoom.coordinate.y;
action(x + 1, y);
action(x - 1, y);
action(x, y + 1);
action(x, y - 1);
Vector2Int newRoomCoordinate = alternativeRoomList[UnityEngine.Random.Range(0, alternativeRoomList.Count)];
startRoom = _roomArray[newRoomCoordinate.x, newRoomCoordinate.y] = CreateRoom(newRoomCoordinate);
alternativeRoomList.Remove(newRoomCoordinate);
}
}
/// <summary>
/// 해당 좌표에 방 생성
/// </summary>
/// <param name="coordinate"></param>
/// <returns></returns>
private Room CreateRoom(Vector2Int coordinate)
{
Room newRoom = Instantiate(_roomPrefab, transform);
newRoom.coordinate = coordinate;
int x = coordinate.x - _roomArray.GetLength(0) / 2;
int y = coordinate.y - _roomArray.GetLength(1) / 2;
newRoom.transform.position = new Vector2(y * Globals.RoomWidth, x * Globals.RoomHeight);
return newRoom;
}
#endregion
}
CreateLevel Method
private void CreateLevel()
{
// 방 생성을 위한 좌표 리스트
List<Vector2Int> alternativeRoomList = new();
List<Vector2Int> hasBeenRemoveRoomList = new();
// 시작 방 생성
int outsetX = _roomArray.GetLength(0) / 2;
int outsetY = _roomArray.GetLength(1) / 2;
Room startRoom = _roomArray[outsetX, outsetY] = CreateRoom(new Vector2Int(outsetX, outsetY));
// 방 생성 델리게이트
Action<int, int> action = (newX, newY) =>
{
Vector2Int coordinate = new(newX, newY);
if (_roomArray[newX, newY] == null)
{
if (alternativeRoomList.Contains(coordinate))
{
alternativeRoomList.Remove(coordinate);
hasBeenRemoveRoomList.Add(coordinate);
}
else if (!hasBeenRemoveRoomList.Contains(coordinate))
{
alternativeRoomList.Add(coordinate);
}
}
};
// 지정된 수 만큼 방 생성
for (int i = 1; i < roomAmount; i++)
{
int x = startRoom.coordinate.x;
int y = startRoom.coordinate.y;
action(x + 1, y);
action(x - 1, y);
action(x, y + 1);
action(x, y - 1);
Vector2Int newRoomCoordinate = alternativeRoomList[UnityEngine.Random.Range(0, alternativeRoomList.Count)];
startRoom = _roomArray[newRoomCoordinate.x, newRoomCoordinate.y] = CreateRoom(newRoomCoordinate);
alternativeRoomList.Remove(newRoomCoordinate);
}
}
- _roomArray는 2차원 배열로, 방이 생성된 위치를 기록한다
- alternativeRoomList는 새로운 방을 생성할 수 있는 후보 좌표를 저장한다
- hasBeenRemoveRoomList는 이미 방이 생성되었지만 나중에 제거될 방의 좌표를 저장한다
- 시작 지점으로 _roomArray의 중심으로부터 start 방을 생성한다
- action 델리게이트 : _roomArray에서 해당 좌표에 방이 없으면 후보 리스트에 추가하거나 삭제한다
- 방 생성 for 문 : 현재 방에서 상하좌우 방향으로 각각 좌표를 체크하고 후보 리스트에 추가하거나 삭제한다
- 후보 리스트에서 무작위로 좌표를 선택하여 새로운 방을 생성하고, 해당 좌표를 후보 리스트에서 삭제한다
CreateRoom Method
private Room CreateRoom(Vector2Int coordinate)
{
Room newRoom = Instantiate(_roomPrefab, transform);
newRoom.coordinate = coordinate;
int x = coordinate.x - _roomArray.GetLength(0) / 2;
int y = coordinate.y - _roomArray.GetLength(1) / 2;
newRoom.transform.position = new Vector2(y * Globals.RoomWidth, x * Globals.RoomHeight);
return newRoom;
}
- 좌표에 따라 새로운 방을 생성, 좌표를 기반으로 방의 위치를 설정하고, 생성된 방을 반환한다
구현 결과
'Unity > Study' 카테고리의 다른 글
유니티 로그라이크 다음 방으로 이동 (0) | 2023.12.19 |
---|---|
유니티 로그라이크 문으로 방 연결하기 (0) | 2023.12.18 |
유니티 Json 데이터 관리 (0) | 2023.12.12 |
유니티 Stat Modifier (0) | 2023.12.11 |
유니티 Manager System (0) | 2023.12.05 |