구현할 부분
아이템 열기구(?) 게임씬에 붙이기.
https://lj9369.tistory.com/129
이 부분에 관해서 R&D를 진행해주신 고마운 팀원님❤의 포스팅을 참고하여 제작해보겠습니댯ㅎ
(1) GameScene에 Zeppelin 생성
오브젝트 풀링 사용
ZeppelinPoolManager
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.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);
}
}
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을 제거하는 함수.
결과
MapController
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--------------------------------------------------
private Queue<GameObject> queueZeppelin = new Queue<GameObject>();
private int installZeppelin;
private int mod = 3;
//----------------------------------------------------------------------------------------------------------------
public void Init()
{
//-----------------------------------------------Zeppelin----------------------------------------------------
ZeppelinPoolManager.instance.Init();
//-----------------------------------------------------------------------------------------------------------
StructurePoolManager.Instance.InitStructure();
this.count = (int)(offset / dis * 2) + 1;
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)
{
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();
//---------------------------------------------------------Zeppelin------------------------------------------
if ((this.installZeppelin++ % mod) == 0)
{
this.UnstallZeppellin();
this.InstallZeppelin();
}
//-----------------------------------------------------------------------------------------------------------
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);
}
private void UnstallZeppellin()
{
GameObject zeppelinGo = this.queueZeppelin.Dequeue();
ZeppelinPoolManager.instance.ReturnZeppelin(zeppelinGo);
}
//--------------------------------------------------------------------------------------------------------------------
}
(2)Zeppelin 폭파 시 아이템 생성 및 이동
RightHandController
팀장님의 스크립트에 추가한 부분.(CoCheckImpact)
Zeppelin을 맞혔을 경우 ZeppelinController의 Hit을 호출.
ZeppelinController
zeppelin hp 할당.
Zeppelin 수명을 다하면 Disable.
ZeppelinPoolManager
queue에 존재하지 않는 disable 상태의 zeppelin을 get.
MapController
zeppelin이 폭발할 때 생성될 itemPrefab들을 저장할 배열 선언.
queue에 들어있는 zeppelin이 멀어질 경우 queue에서 삭제하는 방향으로 변경.
zeppelin이 죽을 경우 호출되는 die.
아이템 생성하는 코루틴 호출.
zeppelin.Init으로 초기화.
아이템 생성하는 함수
Item
기존 팀원님이 작성해주신 코드.
player의 position이 갱신되지 못하여 실패
업데이트 부분으로 이동
요상한 모양새,,,,,
=> Update에서 호출한 DOMove가 사라지지 않고 계속 남아있기 때문.
이에 시도한 방법 : ChangeEndValue
아래의 포스팅을 참고하여 제작.
https://blog.naver.com/dooya-log/221757539272
Tweener 선언
Start에서 tweener 할당
Update에서 ChangeEndValue 사용
첫번째 인자값 : 목표지점(end value)
두번째 인자값 : 목표지점까지 가는데 걸리는 시간
세번째 인자값 : 현재 위치를 기점으로 시작할 것인지의 여부.
Restart : 다시 시작
duration을 계속 같은 값으로 두었을 경우 Item의 속도가 느려질 수 있으므로 duration-=Time.deltaTime으로 시간 줄이기.
Mathf.Clamp 사용하여 duration이 음수가 되는 것을 방지.(duration이 음수일 경우 duration값을 변화시키지 않겠다는 의미가 됨.)
player에 닿으면 destroy.
(3)Score 획득
point(팀원분의 스크립트)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class point : MonoBehaviour
{
public System.Action itemTrigger;
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Item"))
{
Debug.LogFormat("<color=green>itemTrigger</color>");
this.itemTrigger();
}
}
}
GameMain
itemTrigger가 발동하면(아이템을 획득하면) currScore가 증가.
Item
pointTrigger를 향해 아이템이 날아오는 것으로 변경.
결과
'K-digital traning > Final Project' 카테고리의 다른 글
Gazzlers 개발일지 - 로비씬 UI 구현 (0) | 2024.01.04 |
---|---|
Gazzlers 개발일지 - 신규 유저를 위한 게임 안내 (0) | 2024.01.04 |
Gazzlers 개발일지 - WAVE 이후 보상(아이템) 선택 구현 (0) | 2023.12.29 |
Gazzlers 개발일지 - Enemy 공격 (1) | 2023.12.27 |
Gazzlers 개발일지 - Enemy 관리 (0) | 2023.12.21 |