바닥 + 레일을 생성하는 코드를 작성해보았다.
바닥은 기존 작성한 코드를 토대로 생성되게 하였고 레일은 objectpooling을 활용하여 생성되도록 구현하였다.
TestMapMain.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestMapMain : MonoBehaviour
{
[SerializeField] private MapController mapController;
[SerializeField] private CamMove camMove;
// Start is called before the first frame update
void Start()
{
Vector3 camPos = Vector3.zero;
this.mapController.onInformInitPos = (pos) =>
{
camPos = pos;
};
this.mapController.Init();
this.camMove.Init(camPos);
}
}
RailPoolManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RailPoolManager : MonoBehaviour
{
public enum eType
{
Left = 4, Middle = 0, Right = -4
}
public static RailPoolManager Instance;
[SerializeField] private GameObject[] arrRailPrefabs;
private List<GameObject> listLRail = new List<GameObject>();
private List<GameObject> listMRail = new List<GameObject>();
private List<GameObject> listRRail = new List<GameObject>();
private void Awake()
{
if(Instance == null)
Instance = this;
}
public void Init(int count)
{
this.GenerateLRail(count);
this.GenerateMRail(count);
this.GenerateRRail(count);
}
private void GenerateLRail(int count)
{
for(int i=0;i<count;i++)
{
GameObject lRailGo = Instantiate(arrRailPrefabs[0], this.transform);
listLRail.Add(lRailGo);
lRailGo.SetActive(false);
}
}
private void GenerateMRail(int count)
{
for (int i = 0; i < count; i++)
{
GameObject RailGo = Instantiate(arrRailPrefabs[1], this.transform);
listMRail.Add(RailGo);
RailGo.SetActive(false);
}
}
private void GenerateRRail(int count)
{
for (int i = 0; i < count; i++)
{
GameObject RRailGo = Instantiate(arrRailPrefabs[2], this.transform);
listRRail.Add(RRailGo);
RRailGo.SetActive(false);
}
}
public GameObject EnbaleLRail()
{
GameObject result = null;
for(int i = 0; i < listLRail.Count; i++)
{
GameObject go = listLRail[i];
if (go.activeSelf == false)
{
go.SetActive(true);
go.transform.SetParent(null);
result = go;
break;
}
}
return result;
}
public GameObject EnbaleMRail()
{
GameObject result = null;
for (int i = 0; i < listMRail.Count; i++)
{
GameObject go = listMRail[i];
if (go.activeSelf == false)
{
go.SetActive(true);
go.transform.SetParent(null);
result = go;
break;
}
}
return result;
}
public GameObject EnbaleRRail()
{
GameObject result = null;
for (int i = 0; i < listRRail.Count; i++)
{
GameObject go = listRRail[i];
if (go.activeSelf == false)
{
go.SetActive(true);
go.transform.SetParent(null);
result = go;
break;
}
}
return result;
}
public void DisableLRail(GameObject lRailGo)
{
lRailGo.transform.SetParent(this.transform);
lRailGo.transform.position=Vector3.zero;
lRailGo.SetActive(false);
}
public void DisableMRail(GameObject mRailGo)
{
mRailGo.transform.SetParent(this.transform);
mRailGo.transform.position = Vector3.zero;
mRailGo.SetActive(false);
}
public void DisableRRail(GameObject rRailGo)
{
rRailGo.transform.SetParent(this.transform);
rRailGo.transform.position = Vector3.zero;
rRailGo.SetActive(false);
}
}
+ 수정본
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RailPoolManager : MonoBehaviour
{
public static RailPoolManager Instance;
[SerializeField] private GameObject[] arrRailPrefabs;
private List<List<GameObject>> listRail = new List<List<GameObject>>();
private void Awake()
{
if(Instance == null)
Instance = this;
}
public void Init(int count)
{
this.GenerateRail(count);
}
private void GenerateRail(int count)
{
for(int i=0;i<arrRailPrefabs.Length;i++)
{
listRail.Add(new List<GameObject>());
for(int j = 0; j < count; j++)
{
GameObject go = Instantiate(arrRailPrefabs[i], this.transform);
listRail[i].Add(go);
go.SetActive(false);
}
}
}
public GameObject EnableRail(int idx)
{
GameObject result = null;
for(int i = 0; i < listRail[idx].Count; i++)
{
GameObject go = listRail[idx][i];
if (go.activeSelf == false)
{
go.SetActive(true);
go.transform.SetParent(null);
result = go;
break;
}
}
return result;
}
public void DisableRail(GameObject go)
{
go.transform.SetParent(this.transform);
go.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
go.SetActive(false);
}
}
MapController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapController : MonoBehaviour
{
[SerializeField] private GameObject floorPrefab;
[SerializeField] private Transform playerTrans;
private Queue<GameObject> queueFloor = new Queue<GameObject>();
private Queue<System.Tuple<RailPoolManager.eType, GameObject>> queueRail = new Queue<System.Tuple<RailPoolManager.eType, GameObject>>();
private Stack<RailPoolManager.eType> stackRail = new Stack<RailPoolManager.eType>();
private int maxStackSize = 4;
public float offset = 64f;
public float dis = 16f;
private int count;
private Transform lastFloorTrans;
private Vector3 railPos;
public System.Action<Vector3> onInformInitPos;
public void Init()
{
this.count = (int)(offset / dis * 2);
this.InitFloor();
this.InitRail();
}
void Update()
{
this.UpdateMap();
}
private void UpdateMap()
{
while (queueFloor.Count > 0 && queueFloor.Peek().transform.position.z > +playerTrans.position.z + this.offset + this.dis)
{
GameObject floorGo = queueFloor.Dequeue();
this.UnInstallRail();
Vector3 pos = lastFloorTrans.position + Vector3.forward * -this.dis;
floorGo.transform.position = pos;
railPos = pos + Vector3.right * this.CaculateRailOffset();
Debug.LogFormat("<color=cyan>railPos: {0}</color>", railPos);
this.InstallRail();
queueFloor.Enqueue(floorGo);
lastFloorTrans = floorGo.transform;
}
}
private void InitFloor()
{
for (int i = 0; i < count; i++)
{
GameObject floorGo = Instantiate(floorPrefab);
floorGo.transform.position = playerTrans.position + Vector3.forward * (offset - i * this.dis);
queueFloor.Enqueue(floorGo);
if (i == count - 1)
lastFloorTrans = floorGo.transform;
}
}
private void InitRail()
{
RailPoolManager.Instance.Init(this.count);
for(int i = 0; i < this.count; i++)
{
float railOffset = this.CaculateRailOffset();
railPos = playerTrans.position + Vector3.forward * (offset - i * this.dis) + Vector3.right * railOffset;
if (i == this.count / 2)
this.onInformInitPos(railPos);
this.InstallRail();
}
}
private float CaculateRailOffset()
{
float railOffset = stackRail.Count;
if (railOffset > 0)
{
if (stackRail.Peek() == RailPoolManager.eType.Left)
{
railOffset *= 4;
}
else
{
railOffset *= -4;
}
}
return railOffset;
}
private void InstallRail()
{
int rand = Random.Range(0, 10);
if (rand < 3) //LRail
{
if (this.stackRail.Count == this.maxStackSize && this.stackRail.Peek() == RailPoolManager.eType.Left)
{
Debug.Log(stackRail.Peek());
this.InstallRRail();
}
else
this.InstallLRail();
}
else if (rand < 6) //RRail
{
if (this.stackRail.Count == this.maxStackSize && this.stackRail.Peek() == RailPoolManager.eType.Right)
this.InstallLRail();
else
this.InstallRRail();
}
else //MRail
{
this.InstallMRail();
}
}
private void InstallLRail()
{
GameObject go = RailPoolManager.Instance.EnbaleLRail();
System.Tuple<RailPoolManager.eType, GameObject> rail = new System.Tuple<RailPoolManager.eType, GameObject>(RailPoolManager.eType.Left, go);
queueRail.Enqueue(rail);
go.transform.position = this.railPos;
if (this.stackRail.Count == 0 || this.stackRail.Peek() == RailPoolManager.eType.Left)
{
stackRail.Push(RailPoolManager.eType.Left);
}
else if (this.stackRail.Peek() == RailPoolManager.eType.Right)
{
stackRail.Pop();
}
Debug.LogFormat("<color=yellow>stack count:{0}</color>", stackRail.Count);
}
private void InstallMRail()
{
GameObject go = RailPoolManager.Instance.EnbaleMRail();
System.Tuple<RailPoolManager.eType, GameObject> rail = new System.Tuple<RailPoolManager.eType, GameObject>(RailPoolManager.eType.Middle, go);
queueRail.Enqueue(rail);
go.transform.position = this.railPos;
Debug.LogFormat("<color=yellow>stack count:{0}</color>", stackRail.Count);
}
private void InstallRRail()
{
GameObject go = RailPoolManager.Instance.EnbaleRRail();
System.Tuple<RailPoolManager.eType, GameObject> rail = new System.Tuple<RailPoolManager.eType, GameObject>(RailPoolManager.eType.Right, go);
queueRail.Enqueue(rail);
go.transform.position = this.railPos;
if (this.stackRail.Count == 0 || this.stackRail.Peek() == RailPoolManager.eType.Right)
{
stackRail.Push(RailPoolManager.eType.Right);
}
else if (this.stackRail.Peek() == RailPoolManager.eType.Left)
{
stackRail.Pop();
}
Debug.LogFormat("<color=yellow>stack count:{0}</color>", stackRail.Count);
}
private void UnInstallRail()
{
System.Tuple<RailPoolManager.eType, GameObject> rail = queueRail.Dequeue();
switch(rail.Item1)
{
case RailPoolManager.eType.Left:
RailPoolManager.Instance.DisableLRail(rail.Item2);
break;
case RailPoolManager.eType.Middle:
RailPoolManager.Instance.DisableMRail(rail.Item2);
break;
case RailPoolManager.eType.Right:
RailPoolManager.Instance.DisableRRail(rail.Item2);
break;
}
}
}
+ 수정본
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapController : MonoBehaviour
{
[SerializeField] private GameObject floorPrefab;
[SerializeField] private Transform playerTrans;
private Queue<GameObject> queueFloor = new Queue<GameObject>();
private Queue<Rail> queueRail = new Queue<Rail>();
private Stack<Rail.eType> stackRail = new Stack<Rail.eType>();
private int maxStackSize = 3;
public float offset = 112f;
public float dis = 16f;
private int count;
private Transform lastFloorTrans;
private Vector3 railPos;
public System.Action<Vector3> onInformInitPos;
public System.Action<Rail> onInformRoute;
public void Init()
{
this.count = (int)(offset / dis * 2)+1;
this.InitFloor();
this.InitRail();
}
void Update()
{
this.UpdateMap();
}
private void UpdateMap()
{
while (queueFloor.Count > 0 && queueFloor.Peek().transform.position.z > +playerTrans.position.z + this.offset + this.dis)
{
GameObject floorGo = queueFloor.Dequeue();
this.UnInstallRail();
Vector3 pos = lastFloorTrans.position + Vector3.forward * -this.dis;
floorGo.transform.position = pos;
railPos = pos + Vector3.right * this.CalculateRailOffset();
//Debug.LogFormat("<color=cyan>railPos: {0}</color>", railPos);
this.InstallRail();
queueFloor.Enqueue(floorGo);
lastFloorTrans = floorGo.transform;
}
}
private void InitFloor()
{
for (int i = 0; i < count; i++)
{
GameObject floorGo = Instantiate(floorPrefab);
floorGo.transform.position = playerTrans.position + Vector3.forward * (offset - i * this.dis);
queueFloor.Enqueue(floorGo);
if (i == count - 1)
lastFloorTrans = floorGo.transform;
}
}
private void InitRail()
{
RailPoolManager.Instance.Init(this.count);
for(int i = 0; i < this.count; i++)
{
float railOffset = this.CalculateRailOffset();
railPos = playerTrans.position + Vector3.forward * (offset - i * this.dis) + Vector3.right * railOffset;
if (i == this.count / 2)
this.onInformInitPos(railPos);
this.InstallRail();
}
}
private float CalculateRailOffset()
{
float railOffset = stackRail.Count;
if (railOffset > 0)
{
if (stackRail.Peek() == Rail.eType.Left)
{
railOffset *= 4;
}
else
{
railOffset *= -4;
}
}
return railOffset;
}
private void InstallRail()
{
int rand = Random.Range(0, 10);
if (rand < 3) //LRail
{
if (this.stackRail.Count == this.maxStackSize && this.stackRail.Peek() == Rail.eType.Left)
{
//Debug.Log(stackRail.Peek());
this.InstallRRail();
}
else
this.InstallLRail();
}
else if (rand < 6) //RRail
{
if (this.stackRail.Count == this.maxStackSize && this.stackRail.Peek() == Rail.eType.Right)
this.InstallLRail();
else
this.InstallRRail();
}
else //MRail
{
this.InstallMRail();
}
}
private void InstallLRail()
{
GameObject go = RailPoolManager.Instance.EnableRail((int)Rail.eType.Left);
Rail rail = go.GetComponent<Rail>();
queueRail.Enqueue(rail);
go.transform.position = this.railPos;
this.onInformRoute(rail);
if (this.stackRail.Count == 0 || this.stackRail.Peek() == Rail.eType.Left)
{
stackRail.Push(Rail.eType.Left);
}
else if (this.stackRail.Peek() == Rail.eType.Right)
{
stackRail.Pop();
}
//Debug.LogFormat("<color=yellow>stack count:{0}</color>", stackRail.Count);
}
private void InstallMRail()
{
GameObject go = RailPoolManager.Instance.EnableRail((int)Rail.eType.Middle);
Rail rail = go.GetComponent<Rail>();
queueRail.Enqueue(rail);
go.transform.position = this.railPos;
this.onInformRoute(rail);
//Debug.LogFormat("<color=yellow>stack count:{0}</color>", stackRail.Count);
}
private void InstallRRail()
{
GameObject go = RailPoolManager.Instance.EnableRail((int)Rail.eType.Right);
Rail rail = go.GetComponent<Rail>();
queueRail.Enqueue(rail);
go.transform.position = this.railPos;
this.onInformRoute(rail);
if (this.stackRail.Count == 0 || this.stackRail.Peek() == Rail.eType.Right)
{
stackRail.Push(Rail.eType.Right);
}
else if (this.stackRail.Peek() == Rail.eType.Left)
{
stackRail.Pop();
}
//Debug.LogFormat("<color=yellow>stack count:{0}</color>", stackRail.Count);
}
private void UnInstallRail()
{
Rail rail = queueRail.Dequeue();
RailPoolManager.Instance.DisableRail(rail.gameObject);
}
}
결과
'K-digital traning > Final Project' 카테고리의 다른 글
Gazzlers 개발일지 - Map생성(4) (0) | 2023.11.27 |
---|---|
Gazzlers 개발일지 - Map생성(3) (0) | 2023.11.22 |
Gazzlers 개발일지 - Map 생성 (0) | 2023.11.09 |
Gazzlers 개발일지 - Enemy1 GetHit 구현(1) (0) | 2023.11.07 |
Gazzlers 개발일지 - Enemy1 공격 구현 (0) | 2023.11.03 |