무엇을 기준으로?
플레이어 오브젝트의 Input에 따라 맵이 갱신됨.
//PlayerComtroller.cs의 Update 메서드
// 플레이어의 현재 위치를 기반으로 맵을 갱신
mapManager.MoveMap(transform.position.z);
맵은 어떻게 겹치지않게?
맵은 Z방향으로 1씩 누적해서 그 좌표에 생성되면 됨.
똑같이 Z의 Scale이 1이라면 그냥 따로 정해줄 필요가 없겠지만 나는 그라운드별 크기가 다 다르기 때문에 변수를 만들어줘서 넣어줬다.
예를들면 이런식으로 말이다.
// CarRoad.cs
public int scaleNum = 2;
그러면 이제 MapManager.cs가 참조를 해서 ScaleNum의 값을 저장한다.
using System.Collections.Generic;
using UnityEngine;
public class MapManager : MonoBehaviour
{
public ObjectPool objectPool;
public Transform parentTransform;
public int maxPosZ = 10;
private List<GameObject> spawnedObjects = new List<GameObject>();
private float playerZPosition = 0f;
Vector3 currentPosition = Vector3.zero;
void Start()
{
objectPool.Initialize(10);
while (currentPosition.z <= maxPosZ)
{
GameObject roadObj = objectPool.GetObject();
float objLength = GetObjectLength(roadObj);
roadObj.transform.SetParent(parentTransform);
roadObj.transform.localPosition = currentPosition;
// 생성된 오브젝트를 리스트에 추가
spawnedObjects.Add(roadObj);
currentPosition.z += objLength;
}
}
float GetObjectLength(GameObject obj)
{
float length = 0f;
ForestRoad forestRoad = obj.GetComponent<ForestRoad>();
River river = obj.GetComponent<River>();
CarRoad carRoad = obj.GetComponent<CarRoad>();
Road road = obj.GetComponent<Road>();
if (forestRoad != null)
{
length = forestRoad.scaleNum;
}
else if (river != null)
{
length = river.scaleNum;
}
else if (carRoad != null)
{
length = carRoad.scaleNum;
}
else if (road != null)
{
length = road.scaleNum;
}
else
{
Debug.LogWarning("이 오브젝트에 scaleNum 변수명을 가져올 수 없음: " + obj.name);
}
return length;
}
public void MoveMap(float playerZ)
{
playerZPosition = playerZ;
if (spawnedObjects.Count > 0 && playerZPosition > spawnedObjects[0].transform.localPosition.z + GetObjectLength(spawnedObjects[0]))
{
GameObject firstObject = spawnedObjects[0];
spawnedObjects.RemoveAt(0);
// 첫 번째 오브젝트 반환
objectPool.ReturnObject(firstObject);
// 맨 뒤에 새 오브젝트 가져오기
GameObject newRoadObj = objectPool.GetObject();
float objLength = GetObjectLength(newRoadObj);
newRoadObj.transform.SetParent(parentTransform);
newRoadObj.transform.localPosition = currentPosition;
// 현재 위치 업데이트
currentPosition.z += objLength;
spawnedObjects.Add(newRoadObj);
}
}
}
랜덤으로 하고싶지만.. 또.. 처음 태어나는 곳은 흙바닥이여야 한다구요!!
그래서 준비했읍니다. 오죠사마
처음 시작부터 2칸까지는 0번째 배열 인덱스값인 흙바닥으로 가져올 수 있게 하고 그 외는 이제 else문으로 처리했습니다.
오브젝트풀 어렵지 않읍니다..
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool : MonoBehaviour
{
public GameObject[] prefabs;
private Queue<GameObject> pool = new Queue<GameObject>();
public void Initialize(int count)
{
for (int i = 1; i < count; i++)
{
int randomIndex = Random.Range(0, prefabs.Length);
GameObject obj = null;
if(i < 3) // 처음 시작 그라운드
{
obj = Instantiate(prefabs[0]);
}
else
{
obj = Instantiate(prefabs[randomIndex]);
}
obj.SetActive(false);
pool.Enqueue(obj);
}
}
public GameObject GetObject()
{
if (pool.Count > 0)
{
GameObject obj = pool.Dequeue();
obj.SetActive(true);
return obj;
}
else
{
int randomIndex = Random.Range(0, prefabs.Length);
GameObject obj = Instantiate(prefabs[randomIndex]);
obj.SetActive(true);
return obj;
}
}
public void ReturnObject(GameObject obj)
{
obj.SetActive(false);
pool.Enqueue(obj);
}
}
기능 영상
해결해야 하는 부분
현재는 맵을 앞으로 생성을 했음에도 불구하고 뒤로 다시 갈 수 있다. 뒤로 갈 수 없게 막아두거나 하는 로직을 추가해야겠다. 그리고 지금은 같은 프리팹끼리는 다 같은 성능을 가지고 있는데 이걸 다르게 줘볼 수 있게 노력해봐야겠다.
오늘의 회고
자동차.. 자동차 반대로 가는거랑 도로가 조금 어려웠다.
이게 지금은 이게 어려웠나 싶었긴한데 다른건 다 한줄씩 했는데 도로만 2줄짜리라서 새로 이어붙이기를 할때 어떻게 이러붙여야하나 싶었다. 자식의 스케일크기의 값으로도 줘보고 했는데 자꾸 겹쳐지고 그래서 결국 변수를 둬서 해결했다.
아까 난리였던 현장.. 맵 오브젝트들끼리 겹쳐져서 배가 땅을 가고 산을 뚫는다.
자동차 반대로 가는건 그냥 반대로 만들어서 그대로 했는데 이걸 오브젝트 풀로 만드니깐 갑자기 안되는겨.. 한 방향으로밖에 안됨!!!!!!
그래서 계속 지켜보니깐 아예 안되는것처럼 보였는데 그게 아니라 만들어지자마자 비활성화가 되더라.
조건문을 살펴보니
// Car.cs
void CheckDestroy()
{
if(this.ransform.localPosition.x >= destroyDis || this.transform.localPosition.x <= -destroyDis)
{
ReturnToPool();
}
}
void ReturnToPool()
{
gameObject.SetActive(false);
}
자.. 아까까지만해도 잘 됐던게 왜 안되나... 왜 오브젝트풀로 했을때만 안되나..
하면서 여러가지 실험을 해봤다.
럴수가
// this는 생략해도 되는듯합니다 저는 오브젝트에 붙여놔서
if (transform.localPosition.x <= -destroyDis)
{
ReturnToPool();
}
바로 되는 모습을 보여준다.
머리를 쥐어뜯으면서 CarPool 스크립트를 탓하던 나는 바보였다............
아마 새로 생성했을때는 월드좌표기준이였던것같고 오브젝트풀로 했을때는 본인을 기준으로 하는게 아닐까 합니다만.. 잘 모릅니다요 헤헤.. 제가 지정을 어떻게 해주느냐의 차이일 수도 있습니당.
일단 기본적인건 다 끝냈고 점수랑 UI만 끝내면 될 것 같다.
어렵다 어려워
'Record > TIL' 카테고리의 다른 글
[Unity] ScriptableObject (스크립터블 오브젝트) (0) | 2024.06.19 |
---|---|
[Unity] 길건너기 게임 개발 (Feat. 길건너 친구들) (5) | 2024.06.18 |
[Unity] LOD (Level of Detail) (4) | 2024.06.14 |
[Unity] 오브젝트 풀 (2) | 2024.06.13 |
[Unity] 토글 클릭해서 배경음악 변경하기 (0) | 2024.06.12 |