2024-06-20

최종 프로젝트 전, 마지막 팀 프로젝트로 3D 종스크롤 게임을 만들게 되었다.
그 중, 무한히 생성되는 맵 구현을 담당하였다.
플레이어는 맵 오브젝트 밖에 위치하고,
맵 오브젝트를 회전시켜 맵이 계속 반복해서 생성되게 만들었다.
플레이어는 투사체를 발사하고,
몬스터는 Ray를 발사하여 플레이어를 감지해야한다.
그러나, Ray 를 곡선으로 발사할 수 없으며
투사체를 곡선 형태로 발사하기에 계산량이 너무 많아진다.
하나의 맵 타일 안에 많은 오브젝트가 존재해, 맵 타일을 움직이는 것이
많은 계산을 요구한다고 생각하여
맵이 아닌 플레이어가 이동하는 방법으로 기능을 구현하였다.
그러나, 플레이어가 투사체를 발사하거나, 몬스터가 앞으로 이동할 때,
따로 계산을 해주는 작업이 필요하다고 생각하여
팀원들과 상의 후, 맵 타일을 움직이는 방식으로 수정하게 되었다.
설계 (2) 와 마찬가지로, 오브젝트 풀을 사용하고,
플레이어는 고정, 맵이 뒤에서 앞으로 움직이게 하였다.
public class TileManager : MonoBehaviour
{
public static TileManager Instance;
public GameObject[] tilePrefabs;
public Dictionary<int, Queue<GameObject>> TilePool;
public float tileLength = 40.06f; // 타일 길이
public int numberOfTiles = 5;
private void Awake()
{
if (Instance == null)
Instance = this;
TilePool = new Dictionary<int, Queue<GameObject>>();
CreatePool();
}
private void CreatePool()
{
for (int i = 0; i < tilePrefabs.Length; i++)
{
Queue<GameObject> queue = new Queue<GameObject>();
for (int j = 0; j < 5; j++)
{
GameObject go = Instantiate(tilePrefabs[i], transform);
go.SetActive(false);
queue.Enqueue(go);
}
int key = tilePrefabs[i].GetComponent<Tile>().TileId;
TilePool.Add(key, queue);
}
}
public GameObject Get(int id)
{
return TilePool[id].Dequeue();
}
public void Release(int id, GameObject go)
{
TilePool[id].Enqueue(go);
}
void Start()
{
for (int i = 0; i < numberOfTiles; i++)
{
int idx = Random.Range(0, tilePrefabs.Length);
GameObject go = Get(idx);
go.transform.position = transform.forward * (i * tileLength);
go.SetActive(true);
}
}
public void SpawnTile()
{
int idx = Random.Range(0, tilePrefabs.Length);
GameObject go = Get(idx);
go.transform.position = transform.forward * (tileLength * 2);
go.SetActive(true);
Debug.Log("SpawnTile");
}
}
// Tile.cs
public class Tile : MonoBehaviour
{
public int TileId;
private void OnEnable()
{
StartCoroutine(Move());
}
private void Update()
{
if(transform.position.z < -20f)
{
gameObject.SetActive(false);
TileManager.Instance.Release(TileId,gameObject);
TileManager.Instance.SpawnTile();
}
}
IEnumerator Move()
{
while(true)
{
yield return null;
transform.position -= Vector3.forward * 0.1f;
}
}
}
2D 횡스크롤 맵 생성에 대한 참고 자료는 많았으나,
3D 종스크롤 맵 생성에 대한 자료는 찾기 힘들어 많은 고민을 하였다.
처음에는 오브젝트 풀도 List 로 구현하였으나,
Queue 로 구현하는 방식으로 수정하였다.
한 가지 기능을 구현하는 데, 대략 4 - 5번의 수정을 통해 완성하게 되었다.
길고 긴 한 주였다.