🔔 유튜브 크리에이터 골든메탈님의 유니티강의 3D 쿼터뷰 액션게임 [BE5] 를 보고 공부하여 작성한 게시글입니다! 🔔
지난 시간을 끝으로, 유튜브 강의는 끝났습니다. 이제 제가 만들고 싶은 기능들을 차례차례 구현해가면서,
하나둘씩 기능을 만들어보고 싶습니다.
우선은 지난 강의에 이어, 3D 액션게임의 게임의 완성도를 높히는 시간을 가지려고 합니다.
🧷 1. 여러가지 버그 고치기
- 망치로 적들을 처치 시, 몬스터 갯수가 - 가 발생하는 현상
/* GameManager script */
public int enemyCntA;
public int enemyCntB;
public int enemyCntC;
public int enemyCntD;
IEnumerator InBattle(){
while (enemyCntA + enemyCntB + enemyCntC + enemyCntD > 0) {
yield return null;
}
}
GameManger 스크립트에서, Battle이 끝나기 위해서는 필드의 몬스터 수가 0 이상이 되어야지 게임이 끝나는데,
몬스터의 죽는 카운트가 달리 되어버리면 필드에 남아있는 몬스터에 상관없이 Battle이 중단될 수 있습니다.
원인을 찾아보았더니,
/* Enemy Script */
IEnumerator OnDamage(Vector3 reactVec, bool isGrenade){
if(curHealth >0){}
else {
switch (enemyType)
{
case Type.A:
manager.enemyCntA--;
break;
case Type.B:
manager.enemyCntB--;
break;
case Type.C:
manager.enemyCntC--;
break;
case Type.D:
manager.enemyCntD--;
break;
}
}
}
Enemy script의 OnDamage 코루틴에서, 망치에 닿는 순간 코루틴이 계속 돌아가게 되어서, 필드의 몬스터가 죽은 순간에도 몬스터보다 더 많은 카운터가 떨어지는 현상이 일어나게 되는 것이였습니다.
따라서, 이때는 미리 만들어둔 isDead 플래그를 사용하여,
/* Enemy Script */
IEnumerator OnDamage(Vector3 reactVec, bool isGrenade){
if(curHealth >0){}
else {
if(!isDead){
switch (enemyType)
{
case Type.A:
manager.enemyCntA--;
break;
case Type.B:
manager.enemyCntB--;
break;
case Type.C:
manager.enemyCntC--;
break;
case Type.D:
manager.enemyCntD--;
break;
}
}
}
}
enemy가 죽지 않았을 때에만, 카운트가 내려가도록 if문으로 감싸주면 에러를 방지 할 수 있습니다.
- 수류탄이 원하는 방향으로 쏴지지 않은 현상
/* Player Script */
void Grenade(){
if (Physics.Raycast(ray, out rayHit, 100)) {
Vector3 nextVec = rayHit.point - transform.position;
}
}
이때는 수류탄이 나아가는 방향인 nextVec변수에서 ray포인트에서 플레이어 위치를 빼지 않아서 생긴 에러였습니다.
그래서 nextVec = rayHit.point - transform.position을 해주면 마우스를 찍은 위치를 그대로 알 수 있게 됩니다.
- 보스를 처치하여도, 보스가 사라지지 않는 현상
/* Enemy Script */
IEnumerator OnDamage(Vector3 reactVec, bool isGrenade)
{
yield return new WaitForSeconds(0.1f);
if(curHealth > 0) {
}
else {
if (!isDead)
{
//yield return new WaitForSeconds(0.1f);
switch (enemyType)
{
case Type.A:
manager.enemyCntA--;
break;
case Type.B:
manager.enemyCntB--;
break;
case Type.C:
manager.enemyCntC--;
break;
case Type.D:
manager.enemyCntD--;
break;
}
}
Destroy(gameObject, 4);
}
}
Enemy 스크립트에서 몬스터가 처치 될 시, yield return new WaitForSeconds 문이 껴있어서 그 이후의 로직은 제대로 작동이 안되는 것이였습니다. 이 구문을 빼주면 보스도 잘 처치합니다.
/* Boss script */
void Update()
{
if (isDead){
StopAllCoroutines();
return;
}
}
이때 Enemy 스크립트의 OnDamege 코루틴이 yield문을 지나기 전까지 동작을 하였지만
yield 구문이 실행 한 후에는 StopAllCoroutines()인 모든 코루틴이 중단하기 때문에 벌어진 에러였습니다.
++ 추가하고싶은 기능이 있다면 이 게임의 완성도를 높히기 위해서 이동속도, 무기들의 공격력 증가 인 아이템을 만들어서 돈으로 살 수 있게 만들고, 대쉬의 쿨타임을 주면 좋겠다는 생각이 들었습니다. 앞으로 하나하나씩 완성해가는 재미를 느껴봐야겠어요.