[Unity][3D-Game] Tower Defense Game (23)

suhan0304·2023년 12월 28일
0
post-thumbnail

강의영상 (25)


개발

웨이브 스킵 추가

적이 모두 죽으면 Wave가 자동으로 넘어가도록 한다.

WaveSpawner.cs

public static int EnemiesAlive = 0;

void SpawnEnemy()
{
    //미리 지정해둔 스폰 포인트에서 몬스터를 복사해서 소환
    Instantiate(enemyPrefab, spawnPoint.position, spawnPoint.rotation);
    EnemiesAlive++; //몬스터 수 증가
}

이제 Enemy 오브젝트가 죽을 때마다, Enemy가 마지막 WayPoint에 도착해서 파괴됐을때 몬스터 개체 수를 감소시킨다.

Enemy.cs

void Die()
{
    PlayerStats.Money += worth; //플레이어에게 돈 지급

    GameObject effect = (GameObject) Instantiate(deathEffect, transform.position, Quaternion.identity);
    Destroy(effect, 5f);

    WaveSpawner.EnemiesAlive--; //몬스터 개체 수 감소

    Destroy(gameObject);
}

EnemyMovement.cs

void EndPath() //경로의 끝(목표)에 도달
{
    PlayerStats.Lives--; // lives를 1 감소
    WaveSpawner.EnemiesAlive--;
    Destroy(gameObject); //도착지점 도착 시 오브젝트 파괴
}

이제 몬스터 개체수가 0보다 크면 Update를 따로 해주지 않도록 return 시켜서 카운트다운이 몬스터가 모두 죽어야만 실행되도록 수정한다.

WaveSpawner.cs

private void Update()
{
    if (EnemiesAlive >0)
    {
        return;
    }

    if (countdown <= 0f) //카운트다운이 0 보다 작아지먄 Spawn Wave 실행
    {
        
        StartCoroutine(SpawnWave());
        countdown = timeBetweenWaves; //카운트 다운을 중간 시간으로 초기화
        return;
    }

    //deltaTime//마지막 프레임을 그린 후 경과한 시간
    countdown -= Time.deltaTime; //시간을 계속 줄인다.
        
    countdown = Mathf.Clamp(countdown, 0f, Mathf.Infinity); //카운트 다운이 0보다 낮아지지 않도록 설정

    waveCountdownText.text = string.Format("{0:00.00}", countdown); //출력 형식을 지정

    //waveCountdownText.text = Mathf.Round(countdown).ToString();
}

이제 몬스터가 모두 죽어야만 카운트다운이 시작되므로 Wavs 사이의 시간을 2초로 줄여준다.

다양한 Wave 구현

다양한 형태의 Wave를 만들기 위해 Wave 스크립트를 작성한다.

Wave.cs

using UnityEngine;

[System.Serializable]
public class Wave : MonoBehaviour
{
    public GameObject enemy; //Spawn 될 Enemy
    public int count; //Spawn 될 숫자
    public float rate; //Spawn 주기
}

이제 배열 형식으로 waves를 WaveSpawner 스크립트에 선언해주고 Wave 별로 waves배열의 정보를 하나씩 불러와서 해당 웨이브에 맞게 스폰한다.

WaveSpawner.cs

public Wave[] waves;

IEnumerator SpawnWave() //코루틴
{
    PlayerStats.Rounds++;

    Wave wave = waves[waveIndex];

    for (int i = 0; i < wave.count; i++)  //웨이브 레벨만큼 몬스터 소한
    {
        SpawnEnemy(wave.enemy);
        yield return new WaitForSeconds(1f / wave.rate);
    }

    waveIndex++;//웨이브가 올때마다 레벨업
}

void SpawnEnemy(GameObject enemy)
{
    //미리 지정해둔 스폰 포인트에서 몬스터를 복사해서 소환
    Instantiate(enemyPrefab, spawnPoint.position, spawnPoint.rotation);
    EnemiesAlive++;
}

Wave 설정

이제 인스펙터로 Wave에 따른 Enemy와 Count, Rate를 설정해준다.

Enemy는 Enemies 폴더를 새로 만든 후에 기존 Enemy 프리팹을 수정해서 생성해준다. (색을 수정하고 체력, 속도 등, 등을 적절히 조절해서 여러 종류의 적을 만들 수 있다.)

생성한 Enemy 프리팹을 각각의 Wave에 적용시켜 각각의 Wave에 어떤 Enemy가 생성되는지 결정해준다.

이제 생성한 웨이브 수만큼만 Spawn이 진행될 수 있도록 WaveSapwner 스크립트를 수정한다.

WaveSpawner.cs

IEnumerator SpawnWave() //코루틴
{
    PlayerStats.Rounds++;

    Wave wave = waves[waveIndex];

    for (int i = 0; i < wave.count; i++)  //웨이브 레벨만큼 몬스터 소한
    {
        SpawnEnemy(wave.enemy);
        yield return new WaitForSeconds(1f / wave.rate);
    }

    waveIndex++;//웨이브가 올때마다 레벨업

    if (waveIndex == waves.Length)
    {
        Debug.Log("LEVEL WON!");
        this.enabled = false; //WaveSpawner 스크립트를 비활성화
    }
}

결과물

profile
Be Honest, Be Harder, Be Stronger

0개의 댓글