Gazzlers Map 자동생성에 관하여 R&D를 시도(?)해보았다.
GameScene을 보면 Player는 쭉 뒤로 이동하면서 Player 이동에 따라 Map이 화면에 같이 보여진다.
Map을 끝까지 길이 이어 만든 상태로 Player만 이동하게 할 수도 있으나 Map의 크기가 크면 게임에 과부하가 올 수도 있기에 Player 주변부에만 Map이 생성되도록 구현해보고자 한다.

일단 땅같지도 않은 땅 하나를 만들고

TestMapMain도 생성하였다.
이 아이가 player의 위치에 따라 Map을 관리할 것이다.
TestMapMain.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SJY
{
public class TestMapMain : MonoBehaviour
{
[SerializeField] private GameObject groundPrefab;
[SerializeField] private Transform playerTrans;
private Queue<GameObject> queueGround = new Queue<GameObject>();
private int count;
private float offset = 110f;
private Transform lastGroundTrans;
// Start is called before the first frame update
void Start()
{
for (int i = 0; i < 10; i++)
{
GameObject groundGo = Instantiate(groundPrefab);
groundGo.transform.position = playerTrans.position + Vector3.forward * (offset - i * 20);
queueGround.Enqueue(groundGo);
if (i == 9)
lastGroundTrans = groundGo.transform;
}
//Debug.LogFormat("<color=red>lastGround position : {0}</color>", lastGroundTrans.position);
}
// Update is called once per frame
void Update()
{
while (queueGround.Count > 0 && queueGround.Peek().transform.position.z >+ playerTrans.position.z + this.offset+20)
{
Destroy(queueGround.Dequeue());
count++;
}
for (int i = 1; i <= count; i++)
{
GameObject groundGo = Instantiate(groundPrefab);
groundGo.transform.position = lastGroundTrans.position + Vector3.forward * (-i * 20);
queueGround.Enqueue(groundGo);
if (i == count)
{
lastGroundTrans = groundGo.transform;
Debug.LogFormat("<color=yellow>lastGround: {0}</color>", lastGroundTrans.position);
}
}
count = 0;
}
}
}

- groundPrefab : map을 동적으로 생성하기 위해 필요한 Prefab
- playerTrans : player의 위치에 따라 map을 관리할 때 필요한 player의 정보를 알 수 있는 transform
- queueGround : map 관리를 위한 map 저장공간
- count : 생성해야 될 map의 갯수
- offset : player position에 따른 map 위치 조정 및 관리를 위한 값(map의 position.z값의 마지노선으로 생각하면 된다.)
- lastGroundTrans : map을 새로 생성할 때 위치조정을 위한 transform

기본적으로 Scene에 바로 등장할 map 생성
생성한 map들은 queueGround에 Enqueue하여 관리할 수 있도록 한다.(player로부터 멀리 떨어진 순서대로 enqueue한다.)
마지막 위치를 저장하기 위해 lastGroundTrans에 마지막에 생성된 groundGo.transfrom을 할당한다.

queueGround의 맨 앞에 있는 GameObject, 즉 가장 멀리 있는 GameObject의 위치가 player로부터 특정 거리 이상 멀 경우, 즉 player 시야에 보이지 않을 경우 queueGround에서 Dequeue하고 GameObject를 제거한다.
이를 queueGround의 Peek이 player의 시야에 들어올때까지 반복하여 count를 ++한다.
while문을 빠져나온 다음 for문을 돌려 새로운 groundGo를 생성한다.
실행

+
TestMapMain.cs 수정
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestMapMain : MonoBehaviour
{
[SerializeField] private GameObject groundPrefab;
[SerializeField] private Transform playerTrans;
private Queue<GameObject> queueGround = new Queue<GameObject>();
private float offset = 110f;
private Transform lastGroundTrans;
void Start()
{
for (int i = 0; i < 10; i++)
{
GameObject groundGo = Instantiate(groundPrefab);
groundGo.transform.position = playerTrans.position + Vector3.forward * (offset - i * 20);
queueGround.Enqueue(groundGo);
if (i == 9)
lastGroundTrans = groundGo.transform;
}
}
void Update()
{
while (queueGround.Count > 0 && queueGround.Peek().transform.position.z >+ playerTrans.position.z + this.offset+20)
{
GameObject go = queueGround.Dequeue();
go.transform.position = lastGroundTrans.position + Vector3.forward * -20f;
queueGround.Enqueue(go);
lastGroundTrans = go.transform;
}
}
}
변경사항
* map을 수시로 제거 및 생성 -> map의 위치만 변경
'K-digital traning > Final Project' 카테고리의 다른 글
Gazzlers 개발일지 - Map생성(3) (0) | 2023.11.22 |
---|---|
Gazzlers 개발일지 - Map 생성(2) (1) | 2023.11.21 |
Gazzlers 개발일지 - Enemy1 GetHit 구현(1) (0) | 2023.11.07 |
Gazzlers 개발일지 - Enemy1 공격 구현 (0) | 2023.11.03 |
Gazzlers 개발일지 - R&D 목록 (2) | 2023.11.03 |