나만의 것으로 만들기
Coddy의 Unity 게임: 타워 디펜스 코스 레슨. 18개 중 18번째.
게임에는 엔딩이 필요합니다. 목숨이 0이 되면 패배하고, 모든 웨이브가 전송되었으며 보드에 적이 하나도 남지 않으면 승리합니다. 스포너는 마지막 웨이브가 나갔는지 알고, Enemy.All은 적이 몇 명 남았는지 알고 있으므로, 스포너는 보드가 빌 때까지 기다린 다음 GameManager가 수신하는 이벤트를 발생시킵니다. 코루틴은 WaitUntil을 사용해 조건을 기다리며, 이 조건은 람다를 프레임마다 한 번 확인합니다. 모든 스위치가 켜지면 출구가 열리는 퍼즐 방은 다음과 같습니다.
yield return new WaitUntil(() => switchesOn == switches.Length);
exit.SetActive(true);어느 엔딩이든 메시지와 함께 EndPanel을 표시하고 Time.timeScale = 0으로 게임을 멈춥니다. 목숨은 절대로 0 아래로 내려가지 않습니다. 목숨이 1 남았을 때 탱크가 2의 피해를 입으면 정확히 0인지 확인하는 검사를 건너뛰므로, Mathf.Max를 사용해 목숨을 0 이상으로 유지합니다.
다시 플레이를 누르면 씬을 다시 불러옵니다. Time.timeScale은 씬에 속하지 않으며 씬을 불러와도 값이 유지되므로, 0에서 멈춘 게임은 다시 시작해도 멈춘 상태입니다. 따라서 불러오기 전에 값을 다시 1로 설정하세요.
그런 다음 게임을 원하는 대로 바꿔 보세요. 게임 밸런스에 영향을 주는 모든 항목은 Inspector에 있습니다.
- 게임의 GameManager:
startMoney(150) 및startLives(20). - 스포너의
waves: 적, 수량, 간격을 지정하는 8개 행과timeBetweenWaves(8). - EnemyData 에셋: 속도, 체력, 보상, 그리고 각 종류의 적이 감소시키는 목숨 수. 보스는 체력이 450이고 목숨을 10 감소시킵니다.
- TowerData 에셋: 비용, 피해량, 사거리, 발사 속도, 업그레이드 수치, 캐논의 범위 피해, 프로스트 타워의 둔화 효과.
기본 수치는 길의 굽은 곳에 여러 종류의 방어 타워를 배치하고 돈이 들어오는 대로 업그레이드하면 깰 수 있지만, 한 종류의 타워만 몇 개 설치해서는 버티지 못합니다. 한 번에 수치 하나씩 바꾸고, 플레이하면서 어떤 효과가 있는지 확인하세요.
챌린지
어려움WaveSpawner에서public event Action AllWavesCleared를 추가하세요. 마지막 웨이브를 보낸 후Enemy.All이 비워질 때까지 기다린 다음 이벤트를 발생시키세요.GameManager에서 직렬화된 필드endPanel(GameObject)과endText(TMP_Text)를 추가하세요. 목숨은 0 아래로 내려가지 않으며, 0이 되면 게임이Game Over로 끝납니다. 목숨이 남은 상태에서 모든 웨이브를 클리어하면You Win!으로 끝납니다. 게임이 끝나면 메시지와 함께 패널을 표시하고Time.timeScale을 0으로 설정하세요.- 패널의 버튼이 호출하는
public void PlayAgain()을 작성하세요. 시간을 정상으로 되돌리고 활성 씬을 다시 로드합니다.
Play를 눌러 8개 웨이브를 모두 막은 다음 Check를 누르세요. 그 후 Inspector에서 게임을 조정하고 원하는 방식으로 플레이하세요.
직접 해보기
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
[SerializeField] private int startMoney = 100;
[SerializeField] private int startLives = 20;
[SerializeField] private WaveSpawner spawner;
[SerializeField] private TMP_Text moneyText;
[SerializeField] private TMP_Text livesText;
[SerializeField] private TMP_Text waveText;
private int money;
private int lives;
void OnEnable()
{
Enemy.ReachedBase += OnReachedBase;
Enemy.Killed += OnKilled;
spawner.WaveStarted += ShowWave;
}
void OnDisable()
{
Enemy.ReachedBase -= OnReachedBase;
Enemy.Killed -= OnKilled;
spawner.WaveStarted -= ShowWave;
}
void Start()
{
money = startMoney;
lives = startLives;
ShowMoney();
ShowLives();
}
public bool TrySpend(int amount)
{
if (amount > money)
{
return false;
}
money -= amount;
ShowMoney();
return true;
}
public void Earn(int amount)
{
money += amount;
ShowMoney();
}
void OnKilled(Enemy enemy)
{
Earn(enemy.data.reward);
}
void OnReachedBase(Enemy enemy)
{
lives -= enemy.data.damage;
ShowLives();
}
void ShowMoney()
{
moneyText.text = "Money: " + money;
}
void ShowLives()
{
livesText.text = "Lives: " + lives;
}
void ShowWave(int wave, int total)
{
waveText.text = "Wave " + wave + "/" + total;
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.