[4Idle - GroundZero] Zepplin 게임 씬에 추가
https://made-myblog.tistory.com/77
-빈오브젝트를 생성해 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를 수정해주었다.
-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 폭파 시 아이템 생성 및 이동
- Zeppelin을 맞혔을 경우 ZeppelinController의 Hit을 호출
-아이템 프리팹을 생성하고 수정한 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);
}
}
}
-pointTriger를 생성해주고 playerCar의 자식으로 넣어준다.
-GameMain에 pointTrigger를 할당해준다.
'[VR] GroundZero 개발' 카테고리의 다른 글
[4Idle - GroundZero] Player 사망 연출 게임씬에 적용 (1) | 2024.01.09 |
---|---|
[4Idle - GroundZero] Enemy Animation & attack 오브젝트 수정 (0) | 2024.01.08 |
[4Idle - GroundZero] Wave 기능 구현 2 (0) | 2024.01.04 |
[4Idle - Gazzlers] Player의 Score 데이터 연동 및 UI 수정 / 회복 아이템 사용 시 데이터 연동 (0) | 2023.12.28 |
[4Idle - Gazzlers] Enemy의 Player 공격 GameScene에 적용 (1) | 2023.12.28 |