-
[Rollick 개발 일지] 02. 주변 건물 무작로 생성하기카테고리 없음 2023. 10. 21. 22:07
지난 시간엔 스케이트 보드가 길을 끊김 없이 가는 기능을 구현하였다.
하지만 이렇게만 구현한다면 주변 건물들이 계속 반복적으로만 나타나 플레이어가 단조로움을 느낄 수 있다.
우선 랜덤적으로 배치할 건물들을 4개씩 묶어 총 7개의 프리팹을 제작하였다. 이 프리팹들을 도로의 주변에 랜덤적으로
배치할 예정이다.
생각한 로직은 이렇다.
이 로직을 기반으로 작성한 코드는 아래와 같다.
[System.Serializable] public class BuildingElement { public Transform building; // 빌딩 프리팹 public float nextBuildingPosIdx; // 다음 빌딩과 떨어져야 하는 간격 } public class BuildingInstallFunc : MonoBehaviour { public List<BuildingElement> buildingList = new List<BuildingElement>(); private List<BuildingElement> _buildings = new List<BuildingElement>(); private BuildingElement _saveBuilding = null; private float _positionValue; private Dictionary<Transform, List<Transform>> _loadData = new Dictionary<Transform, List<Transform>>(); private void CombineBuilding(Transform load, Transform buildingTrans) // 도로에 배치된 건물 저장 { if(!_loadData.ContainsKey(load)) { List<Transform> buildingDatas = new List<Transform>(); buildingDatas.Add(buildingTrans); _loadData.Add(load, buildingDatas); return; } _loadData[load].Add(buildingTrans); } public void ResetBuilding(Transform load) // 도로에 배치된 빌딩 초기화 { if (!_loadData.ContainsKey(load)) return; foreach(Transform t in _loadData[load]) { Destroy(t.gameObject); //PoolManager로 교체 예정 } _loadData[load].Clear(); } public void RandomBuild(Transform parent) // 도로에 건물 무작위로 배치 { _saveBuilding = null; _positionValue = 0; _buildings.Clear(); for (int i = 0; i < buildingList.Count; i++) _buildings.Add(buildingList[i]); for (int i = 0; i < 4; i++) { int idx = Random.Range(0, _buildings.Count); BuildingElement select = _buildings[idx]; Transform selectTrm = Instantiate(select.building, parent); CombineBuilding(parent, selectTrm); if(_saveBuilding != null) { _positionValue += _saveBuilding.nextBuildingPosIdx; selectTrm.position += new Vector3(_positionValue, 0, 0); } if (_saveBuilding != null) _buildings.Add(_saveBuilding); _saveBuilding = _buildings[idx]; _buildings.RemoveAt(idx); // 다음 생성되는 빌딩이 똑같은 빌딩이 생성되선 안되니 // 삭제처리 해주었다. } } }
잘 동작하는 모습이다. 하지만 오른쪽 부분만 맵이 생성되며 도로와 도로 사이에 자투리 공간 또한 존재한다.
자투리 공간은 도로 프리팹을 조금 손봐 손쉽게 해결할 수 있다. 하지만 왼쪽 부분에 생성될 건물들은 건물이 바라보는
방향이 달라야 한다.
오른쪽 건물 4개, 왼쪽 건물 4개를 배치하기 위해선 총 8번 반복을 해야 하고 for문의 int i를 2로 나누어 나머지가 0이면
왼쪽, 1이면 오른쪽으로 판단하기로 했다.
public void RandomBuild(Transform parent) // 도로에 건물 무작위로 배치 { _saveBuilding = null; _positionValue = new float[2] { 0, 0 }; _buildings.Clear(); _saveBuilding = new BuildingElement[2] { null, null }; for (int i = 0; i < buildingList.Count; i++) _buildings.Add(buildingList[i]); for (int i = 0; i < 8; i++) { int divideRL = i % 2; int idx = Random.Range(0, _buildings.Count); BuildingElement select = _buildings[idx]; Transform selectTrm = Instantiate(select.building, parent); if (_saveBuilding[divideRL] != null) { _positionValue[divideRL] += _saveBuilding[divideRL].nextBuildingPosIdx; _buildings.Add(_saveBuilding[divideRL]); } selectTrm.position += new Vector3(_positionValue[divideRL], 0, 31 * (divideRL)); foreach (Transform child in selectTrm) { child.rotation = Quaternion.Euler(0, 180 * (divideRL), 0); } _saveBuilding[divideRL] = _buildings[idx]; _buildings.RemoveAt(idx); CombineBuilding(parent, selectTrm); } }
완성된 메서드이다.
잘 작동하는 모습이다.
다음 포스팅에서 뵙겠습니다.