[4Idle - GroundZero] Zepplin 게임 씬에 추가

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

 

Gazzlers 개발일지 - Zeppelin 생성

구현할 부분 아이템 열기구(?) 게임씬에 붙이기. https://lj9369.tistory.com/129 Gazzlers R&D - 아이템 비행체 구현 ▼ 구현할 부분 ▼ 구현할 것 - 비행체를 레이로 조준하여 3번 맞추기 --> 비행체 사라지고

made-myblog.tistory.com

-빈오브젝트를 생성해 ZepplinPoolManager라 명명하고 스크립트를 넣어준다.

-Zeppelin Prefab에 프리팹을 할당해준다. 프리팹에는 Zeppelin Controller가 부착되어있다.

 

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

public class ZeppelinPoolManager : MonoBehaviour
{
    [SerializeField] private GameObject zeppelinPrefab;
    private List<GameObject> listZeppelin = new List<GameObject>();

    public static ZeppelinPoolManager instance;
    private void Awake()
    {
        instance = this;
    }

    public void Init()
    {
        for (int i = 0; i < 10; i++)
        {
            GameObject go = this.GenerateZeppelin();
            go.SetActive(false);
        }
    }

    private GameObject GenerateZeppelin()
    {
        GameObject go = Instantiate(zeppelinPrefab, this.transform);
        this.listZeppelin.Add(go);
        return go;
    }

    public GameObject GetZeppelin()
    {
        GameObject result = null;
        for (int i = 0; i < this.listZeppelin.Count; i++)
        {
            GameObject go = listZeppelin[i];
            if (go.activeSelf == false && go.transform.parent == this.transform)
            {
                go.transform.SetParent(null);
                go.SetActive(true);
                result = go;
                break;
            }
        }
        if (result == null)
        {
            result = this.GenerateZeppelin();
            result.transform.SetParent(null);
        }
        return result;
    }

    public void ReturnZeppelin(GameObject go)
    {
        go.transform.SetParent(this.transform);
        go.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
        go.SetActive(false);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

   public class ZeppelinController : MonoBehaviour
{
    private int zeppelinMaxHp = 3;
    private int zeppelinHp;
    public float speed = 0.7f;
    [SerializeField] private GameObject effect;
    public System.Action<Vector3> die;

    public void Init()
    {
        this.zeppelinHp = this.zeppelinMaxHp;
    }

    void Update()
    {
        //this.transform.Translate(Vector3.forward * this.speed * Time.deltaTime);
    }

    public void Hit()
    {
        this.zeppelinHp--;
        if (this.zeppelinHp == 0)
        {
            this.die(this.transform.position);
            Instantiate(this.effect, this.transform.position, Quaternion.identity);
            //Destroy(this.gameObject);
            this.gameObject.SetActive(false);
            //ZeppelinPoolManager.instance.ReturnZeppelin(this.gameObject);
        }
    }
}

 

 

-MapController를 수정해주었다.

Zeppelin을 설치 / ZeppelinPoolManager가 Zeppelin을 생성

 

-MapController의 UpdateMap 함수 수정 부분.

3번(mod)에 한 번씩 zeppelin이 제거 및 설치되도록 구현.

 

-InitRail함수를 InitRailAndZeppelin으로 수정

Rail을 설치할 때 Rail 근처로 Zeppelin이 설치되도록 구현. 이것도 역시 3번(mod)에 한번 꼴.

 

 

InstallZeppelin은 Zeppelin을 설치하는 함수.

Zeppelin의 생성 위치를 담당할 pos는 방금 설치된 Rail의 근처로 할당된다.

생성된 Zeppelin을 관리할 queueZeppelin에 생성된 zeppelinGo를 enqueue.

UninstallZeppelin은 설치한 zeppelin을 제거하는 함수.

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

    public class MapController : MonoBehaviour
    {
        [SerializeField] private GameObject floorPrefab;
        [SerializeField] private Transform playerTrans;
        [SerializeField] private StructureManager structureManager;
        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;
    //------------------------------------------------------Zeppelin--------------------------------------------------
    [SerializeField] private GameObject[] itemPrefabs;
    private Queue<GameObject> queueZeppelin = new Queue<GameObject>();
    private int installZeppelin;
    private int mod = 3;
    //----------------------------------------------------------------------------------------------------------------

    public void Init()
        {

        //-----------------------------------------------Zeppelin----------------------------------------------------
        ZeppelinPoolManager.instance.Init();
        //-----------------------------------------------------------------------------------------------------------
        this.count = (int)(offset / dis * 2) + 1;
            RailPoolManager.Instance.Init(this.count);
            StructurePoolManager.Instance.InitStructure();
            this.InitFloor();
            this.InitRailAndZeppelin();
        }

        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();
               
                this.InstallRail();
            //---------------------------------------------------------Zeppelin------------------------------------------
            if ((this.installZeppelin++ % mod) == 0)
            {
                //this.UnstallZeppelin();
                this.InstallZeppelin();
            }
            while (queueZeppelin.Count > 0 && queueZeppelin.Peek().transform.position.z > this.playerTrans.position.z + this.offset)
                this.UinstallZeppelin();
            //-----------------------------------------------------------------------------------------------------------

            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 InitRailAndZeppelin()
    {
        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 (railPos.z == 0)
                this.onInformInitPos(railPos);
            if (railPos.z >= 0)
            {
                this.InstallMRail();
            }
            else
                this.InstallRail();
            //---------------------------------------Zeppelin-----------------------------------------------
            if ((this.installZeppelin++ % mod) == 0)
                this.InstallZeppelin();
            //----------------------------------------------------------------------------------------------
        }
    }
    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 < 2)                   //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 < 4)              //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;
            //structure 생성
            structureManager.InstallStructure(rail);

            //루트 알려주기
            this.onInformRoute(rail);

            //stack에 저장
            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;

            structureManager.InstallStructure(rail);

            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;

            structureManager.InstallStructure(rail);

            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);
            structureManager.UninstallStructure();
        }


    //--------------------------------------------------------Zeppelin----------------------------------------------------
    private void InstallZeppelin()
    {
        GameObject zeppelinGo = ZeppelinPoolManager.instance.GetZeppelin();
        Vector3 pos = this.railPos + Vector3.right * Random.Range(-10f, 10f) + Vector3.up * 10f + Vector3.forward * Random.Range(-12f, -3f);
        zeppelinGo.transform.position = pos;
        this.queueZeppelin.Enqueue(zeppelinGo);
        var zeppelin = zeppelinGo.GetComponent<ZeppelinController>();
        zeppelin.die = (pos) =>
        {
            this.StartCoroutine(this.CoCreateItem(pos));
        };
        zeppelin.Init();
    }

    private void UinstallZeppelin()
    {
        GameObject zeppelinGo = this.queueZeppelin.Dequeue();
        ZeppelinPoolManager.instance.ReturnZeppelin(zeppelinGo);
    }

    private IEnumerator CoCreateItem(Vector3 pos)
    {
        for (int i = 0; i < 10; i++)
        {
            var rotation = Quaternion.Euler(Random.Range(0.0f, 360.0f), Random.Range(0.0f, 360.0f), Random.Range(0.0f, 360.0f));
            yield return new WaitForSeconds(0.1f);

            //아이템 2가지 중 랜덤 생성
            Instantiate(itemPrefabs[Random.Range(0, this.itemPrefabs.Length)], pos, rotation);
        }
    }
    //--------------------------------------------------------------------------------------------------------------------
}

 

Zeppelin 폭파 시 아이템 생성 및 이동

 

rightHandController.cs 수정

- Zeppelin을 맞혔을 경우 ZeppelinController의 Hit을 호출

 

아이템 생성후 Item 스크립트 부착 / mapController에 프리팹 할당

-아이템 프리팹을 생성하고 수정한 MapController에 프리팹들을 할당해준다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class Item : MonoBehaviour
{
    private Transform pointTriggerTrans;
    public float duration = 0.7f;
    private Tweener tweener;

    void Start()
    {
        this.pointTriggerTrans = GameObject.Find("pointTrigger").transform;
        this.tweener = this.transform.DOMove(this.transform.position, this.duration).SetAutoKill(false).SetEase(Ease.InOutQuad);

    }
    void Update()
    {
        this.duration -= Time.deltaTime;
        this.duration = Mathf.Clamp(this.duration, 0.0001f, this.duration);
        this.tweener.ChangeEndValue(this.pointTriggerTrans.position, this.duration, true).Restart();
      
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            Debug.LogFormat("<color=yellow>Trigger</color>");
            this.tweener.Kill();
            Destroy(this.gameObject);
        }
    }
}

playerCar의 자식으로 pointTrigger 생성

-pointTriger를 생성해주고 playerCar의 자식으로 넣어준다.

GameMain 수정
Gamemain에 pointTrigger 할당

-GameMain에 pointTrigger를 할당해준다.

 

myoskin