새소식

🎮 Game Dev (게임개발)/PC (데스크탑, 노트북, 터치패널)

[3D 액션게임] 18. 버그 고치기

  • -

🔔 유튜브 크리에이터 골든메탈님의 유니티강의 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()인 모든 코루틴이 중단하기 때문에 벌어진 에러였습니다.

 

 

++ 추가하고싶은 기능이 있다면 이 게임의 완성도를 높히기 위해서 이동속도, 무기들의 공격력 증가 인 아이템을 만들어서 돈으로 살 수 있게 만들고, 대쉬의 쿨타임을 주면 좋겠다는 생각이 들었습니다. 앞으로 하나하나씩 완성해가는 재미를 느껴봐야겠어요.

 

 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.