K-digital traning/Final Project

Gazzlers 개발일지 - Map 생성

내꺼블로그 2023. 11. 9. 18:20

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;
        }
    }
}

 

 

 

 

 

 

 

 

 

TestMapMain의 property

 

- groundPrefab : map을 동적으로 생성하기 위해 필요한 Prefab

- playerTrans : player의 위치에 따라 map을 관리할 때 필요한 player의 정보를 알 수 있는 transform

- queueGround : map 관리를 위한 map 저장공간

- count : 생성해야 될 map의 갯수

- offset : player position에 따른 map 위치 조정 및 관리를 위한 값(map의 position.z값의 마지노선으로 생각하면 된다.)

- lastGroundTrans : map을 새로 생성할 때 위치조정을 위한 transform

 

 

 

 

 

TestMapMain의 Start Method

 

 

기본적으로 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의 위치만 변경