[4Idle - Gazzlers] GameScene 맵 수정

-현재 GameScene은 동적으로 맵을 생성하는데, 미완성이라 나무만 무작위로 생겨나고 있었다.

- 이를 수정하여

건물들과 램프 등이 생성되도록 수정하려한다.

 

https://made-myblog.tistory.com/70

 

Gazzlers 개발일지 - Map 수정(with CurvedWorld)

현재 map의 분위기가 단조롭고 평화로워 게임컨셉과는 다소 이질적이다는 피드백을 받아 이를 수정해보고자 한다. 우선 분위기를 저해하는 트리를 제거하였다. StructureManager 스크립트에서도 트

made-myblog.tistory.com

-팀원분이 수정해주신 맵을 토대로 GameScene을 수정할 것이다.

-CurvedWorld를 사용하여 지면도 휘어지도록 처리하였다.

- 관련된 오브젝트들의 material이 수정되어야한다.

 

-빈오브젝트를 생성하고 curvedworld Controller를 부착한다.

-BendType 을 ClassicRunner(Z positive)로 설정하고 Bend Settings 의 Vertical을 -2로 해준다.

-Pivod Point의 Transform에 PlayerCar를 할당한다.

structure.cs
StructureManager.cs

-수정된 structure스크립트를 달아주고 프리팹들마다 type을 다르게 변경해준다.

-Structure Pool Manager에 새로운 프리팹들을 할당해준다.

 

 

맵 수정 후 빌드 결과 enemy 1,2,3

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System;


    public class EnemyMove : MonoBehaviour
    {

        public enum eEnemyType
        {
            Enemy1, Enemy2, Enemy3
        }

        public eEnemyType enemyType;

        public KeyValuePair<int, Transform> target;
        protected bool isReady;
        public float moveSpeed = 5.5f;
        public float rotSpeed = 8f;
        public float changeTargetTime = 5f;

        public float trackingTargetTime = 2f;
        private float elapsedTime = 3f;

        public float offset = 0.5f;
        public float length = 3.5f;
        public int depth = 3;
        public Action<int> onChangeTarget;
        protected Rigidbody rBody;
        private List<Tuple<Ray, bool>> listRays = new List<Tuple<Ray, bool>>();
        private Vector3 dir;
        private bool isDetected;

        private void FixedUpdate()
        {
            if (!this.isReady) return;
            this.Detect();
            this.DecideDir();
            this.Move();
        }

        private void Start()
        {
            this.rBody = this.GetComponent<Rigidbody>();
        }

        virtual public void Init(Vector3 pos)
        {
            //..Enemy 위치 지정 후
            this.transform.position = pos;
            //..활성화(보여주기)
            this.gameObject.SetActive(true);
        }

        virtual public void Detect()
        {
            this.listRays.Clear();
            this.isDetected = false;
            Vector3[] pos = new Vector3[] { this.transform.right, -this.transform.right, this.transform.forward };
            for (int i = 0; i < pos.Length; i++)
            {
                Ray ray = new Ray(this.transform.position + Vector3.up * this.offset, pos[i]);
                DrawAndHitRay(ray);
            }
            for (int i = 0; i < 2; i++)
            {
                this.RecurDrawAndHitRay(pos[i], pos[2], 0);
            }
        }

        virtual public void Move()
        {
            float curSpeed = this.moveSpeed;
            float posZ = this.transform.position.z;
            float targetPosZ = this.target.Value.position.z;
            if (posZ > targetPosZ + 15)
            {
                curSpeed = this.moveSpeed * 1.5f;
            }
            else if (posZ > targetPosZ + 7)
            {
                curSpeed = this.moveSpeed;
            }
            else if (posZ > targetPosZ + 3)
            {
                curSpeed = this.moveSpeed * 0.9f;
            }
        if (this.isDetected) curSpeed *= 0.8f;
        //float velocityY = this.rBody.velocity.y;
        //this.rBody.velocity = this.transform.forward * curSpeed;
        //this.rBody.velocity += Vector3.up * velocityY;
        this.rBody.MovePosition(this.rBody.position + this.transform.forward * curSpeed * Time.fixedDeltaTime);
        //Debug.LogFormat("<color=green>curspeed: {0}</color>", curSpeed);
    }


    virtual public void DecideDir()
        {
            List<List<Ray>> listNotHitRays = new List<List<Ray>>();
            List<Tuple<Ray, bool>> newListRays = listRays.OrderBy(x => Vector3.Distance(x.Item1.direction, this.transform.right)).ToList();
            for (int i = 0; i < newListRays.Count; i++)
            {
                Tuple<Ray, bool> tupleRay = newListRays[i];

                if (!tupleRay.Item2)
                {
                    if (listNotHitRays.Count == 0)
                    {
                        listNotHitRays.Add(new List<Ray>());
                    }
                    listNotHitRays[listNotHitRays.Count - 1].Add(tupleRay.Item1);
                    if (i < newListRays.Count - 1 && newListRays[i + 1].Item2)
                    {
                        listNotHitRays.Add(new List<Ray>());
                    }
                }
            }
            if (this.isDetected)
            {
                this.elapsedTime = 0f;

                int maxCount = 0;
                int maxCountIndex = 0;
                for (int i = 0; i < listNotHitRays.Count; i++)
                {
                    if (listNotHitRays[i].Count > maxCount)
                    {
                        maxCount = listNotHitRays[i].Count;
                        maxCountIndex = i;
                    }
                }

                this.dir = Vector3.zero;
                for (int i = 0; i < listNotHitRays[maxCountIndex].Count; i++)
                {
                    this.dir += listNotHitRays[maxCountIndex][i].direction;
                }
                this.dir /= maxCount;
                this.transform.rotation = Quaternion.Lerp(this.transform.localRotation, Quaternion.LookRotation(this.dir), this.rotSpeed * Time.deltaTime);
            }
            else
            {
                this.elapsedTime += Time.deltaTime;
                if (this.elapsedTime > this.trackingTargetTime)
                {
                    this.dir = this.target.Value.position - this.transform.position;
                    //Debug.LogFormat("<color=red>{0}</color>", Quaternion.LookRotation(this.dir));
                    this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.LookRotation(this.dir), this.rotSpeed * Time.deltaTime * 0.6f);
                }
                else
                    this.transform.rotation = Quaternion.Lerp(this.transform.localRotation, Quaternion.LookRotation(this.dir), this.rotSpeed * Time.deltaTime);
            }
        }

        virtual public void RecurDrawAndHitRay(Vector3 pos1, Vector3 pos2, int depth)
        {
            Ray ray = new Ray(this.transform.position + Vector3.up * this.offset, (pos1 + pos2).normalized);
            this.DrawAndHitRay(ray);
            if (depth < this.depth)
            {
                this.RecurDrawAndHitRay(pos1, (pos1 + pos2).normalized, depth + 1);
                this.RecurDrawAndHitRay(pos2, (pos1 + pos2).normalized, depth + 1);
            }
        }

        virtual public void DrawAndHitRay(Ray ray)
        {
            int layerMask = 1 << 3 | 1 << 6 | 1 << 7;
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, this.length, layerMask))
            {
                this.isDetected = true;
                Debug.DrawRay(ray.origin, ray.direction.normalized * this.length, Color.red);
                this.listRays.Add(new Tuple<Ray, bool>(ray, true));
            //    Debug.LogFormat("<color=blue>hit</color>: {0}", hit.collider.gameObject);
            }
            else
            {
                Debug.DrawRay(ray.origin, ray.direction.normalized * this.length, Color.green);
                this.listRays.Add(new Tuple<Ray, bool>(ray, false));
            }
        }

        virtual public void UpdateTargetPos(int idx, Transform targetTrans)
        {
            this.target = new KeyValuePair<int, Transform>(idx, targetTrans);
            if (!isReady)
            {
                isReady = true;
                this.StartCoroutine(this.CoChangeTarget());
            }
        }

        virtual public IEnumerator CoChangeTarget()
        {
            while (true)
            {
                yield return new WaitForSeconds(this.changeTargetTime);
                this.onChangeTarget(this.target.Key);
            }
        }

        virtual public void OnDrawGizmos()
        {
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(this.transform.position, 2f);
        }


    }
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System;

    public class EnemyPoolManager : MonoBehaviour
    {
        public static EnemyPoolManager instance;
        //[SerializeField] private GameObject enemyPrefab;
        [SerializeField] private GameObject[] arrEnemyPrefabs;
        // private List<Enemy1Move> enemyPool = new List<Enemy1Move>();
         private List<List<GameObject>> enemyPool = new List<List<GameObject>>();

        void Awake()
        {
            instance = this;
        }


        private void Start()
        {
            this.GenerateEnemy();
        }

        private void GenerateEnemy()
        {
           // for (int i = 0; i < 2; i++)
            for(int i=0;i<this.arrEnemyPrefabs.Length; i++)    
            {
                List<GameObject> list = new List<GameObject>();
                for (int j = 0; j < 2; j++)
                {
                    GameObject go = Instantiate(arrEnemyPrefabs[i], this.transform);
                    go.SetActive(false);
                    list.Add(go);
                    //GameObject go = Instantiate(enemyPrefab, this.transform);
                    //go.SetActive(false);
                    //enemyPool.Add(go.GetComponent<Enemy1Move>());

                }
                this.enemyPool.Add(list);
                }
        }

        public GameObject EnableEnemy(int idx)
        {
            GameObject result = null;

            for (int i = 0; i < enemyPool[idx].Count; i++)
            {
            //  Debug.Log(enemyPool[idx][i]);
            if (enemyPool[idx][i].activeSelf == false)
            {
                result = enemyPool[idx][i];
                //result.gameObject.SetActive(true);
                result.transform.SetParent(null);
                break;
            }
        }
        if (result == null)
        {
            result = Instantiate(arrEnemyPrefabs[idx]);
            enemyPool[idx].Add(result);
        }
        return result;


        }

        public void DisableEnemy(GameObject enemy)
        {
            enemy.SetActive(false);
            enemy.transform.SetParent(this.transform);
        }

    }
using System.Collections;
using System.Collections.Generic;
using UnityEngine;



  
    public class StructureManager : MonoBehaviour
    {
    private Queue<List<Structure>> qStructures = new Queue<List<Structure>>();
    private bool install;
    private bool uninstall;

    public void InstallStructure(Rail rail)
    {
        if (!(this.install ^= true)) return;
        List<Structure> list = new List<Structure>();
        int type = Random.Range((int)Structure.eType.ARCHITECTURE1, (int)Structure.eType.ARCHITECTURE3 + 1);
        GameObject go = StructurePoolManager.Instance.EnableStructure(type);
        go.transform.position = rail.transform.position;
        list.Add(go.GetComponent<Structure>());
        int rand = Random.Range(0, 2);
        GameObject pole;
        if (rand % 2 == 0)
        {
            pole = StructurePoolManager.Instance.EnableStructure((int)Structure.eType.LAMP);
        }
        else
        {
            pole = StructurePoolManager.Instance.EnableStructure(((int)Structure.eType.CLOCK));
        }
        float[] dirx = new float[] { -1, 1 };
        pole.transform.position = rail.transform.position + Vector3.left * dirx[Random.Range(0, dirx.Length)] * Random.Range(5f, 7f) + Vector3.back * Random.Range(1f, 15f);
        list.Add(pole.GetComponent<Structure>());
        qStructures.Enqueue(list);
    }

    public void UninstallStructure()
    {
        if (!(this.uninstall ^= true) || qStructures.Count == 0) return;
        List<Structure> list = qStructures.Dequeue();
        for (int i = 0; i < list.Count; i++)
        {
            StructurePoolManager.Instance.DisableStructure(list[i].gameObject);
        }
    }
}
myoskin