K-digital traning/Final Project

Gazzlers 개발일지 - Map 생성(2)

내꺼블로그 2023. 11. 21. 16:21

바닥 + 레일을 생성하는 코드를 작성해보았다.

바닥은 기존 작성한 코드를 토대로 생성되게 하였고 레일은 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);
        }
    }

 

 

 

 

 

 

 

 

 

결과