로직 구현
근거리 몹의 데미지를 구현하기 위해 Collider를 하나 더 달아서 Trigger로 만들어준다.
GameManager에 로직을 추가한다. 아래 IEnumerator StartNextWave()는 Coroutine(코루틴)이다. 코루틴은 비동기적으로 실행되는 함수로, 특정 부분에서 일시적으로 멈추거나 다시 시작하게 한다.
Start에서 코루틴을 실행하고 GameOver가 되면 멈춘다. 소환된 몹이 0이 되면(첫 시작이거나 다 잡았거나) Wave를 최신화 해준다.
[SerializeField] private int currentWaveIndex = 0;
private int currentSpawnCount = 0;
private int waveSpawnCount = 0;
private int waveSpawnPosCount = 0;
public float spawnInterval = .5f;
public List<GameObject> enemyPrefebs = new List<GameObject>();
[SerializeField] private Transform spawnPositionsRoot;
private List<Transform> spawnPostions = new List<Transform>();
private void Awake()
{
instance = this;
Player = GameObject.FindGameObjectWithTag(playerTag).transform;
playerHealthSystem = Player.GetComponent<HealthSystem>();
playerHealthSystem.OnDamage += UpdateHealthUI;
playerHealthSystem.OnHeal += UpdateHealthUI;
playerHealthSystem.OnDeath += GameOver;
gameOverUI.SetActive(false);
for (int i = 0; i < spawnPositionsRoot.childCount; i++)
{
spawnPostions.Add(spawnPositionsRoot.GetChild(i));
}
}
private void Start()
{
UpgradeStatInit();
StartCoroutine("StartNextWave");
}
// 코루틴
IEnumerator StartNextWave()
{
while(true)
{
if(currentSpawnCount == 0)
{
UpdateWaveUI();
yield return new WaitForSeconds(2f);
if(currentWaveIndex % 20 == 0)
{
// 업그레이드
}
if(currentWaveIndex % 10 == 0)
{
waveSpawnPosCount = waveSpawnPosCount + 1 > spawnPostions.Count ? waveSpawnPosCount : waveSpawnPosCount + 1;
waveSpawnCount = 0;
}
if(currentWaveIndex % 5 ==0)
{
// 보상
}
if(currentWaveIndex % 3 == 0)
{
waveSpawnCount += 1;
}
for(int i = 0; i < waveSpawnPosCount;i++)
{
int posIdx = Random.Range(0, spawnPostions.Count);
for(int j = 0; j <waveSpawnCount;j++)
{
int prefabIdx = Random.Range(0,enemyPrefebs.Count);
GameObject enemy = Instantiate(enemyPrefebs[prefabIdx], spawnPostions[posIdx].position, Quaternion.identity);
enemy.GetComponent<HealthSystem>().OnDeath += OnEnemyDeath;
currentSpawnCount++;
yield return new WaitForSeconds(spawnInterval);
}
}
currentWaveIndex++;
}
yield return null;
}
}
private void OnEnemyDeath()
{
currentSpawnCount--;
}
private void GameOver()
{
gameOverUI.SetActive(true);
StopAllCoroutines();
}
private void UpdateWaveUI()
{
waveText.text = (currentWaveIndex + 1).ToString();
}
유니티로 돌아와서 적 스폰지점을 만들고 GameManager에 알려준다.
아이템 구현
아이템 구현을 위해 스크립트를 만든다. PickupItem 스크립트로 아이템을 생성하진 않을 것이기 때문에 추상 클래스로 만든다.
아이템을 먹었을 때 삭제할 것인지, 아이템을 먹을 수 있는 레이어, 오디오를 추가한다.
[SerializeField] private bool destroyOnPickup = true;
[SerializeField] private LayerMask canBePickupBy;
[SerializeField] private AudioClip pickupSound;
private void OnTriggerEnter2D(Collider2D other)
{
if (canBePickupBy.value == (canBePickupBy.value | (1 << other.gameObject.layer)))
{
OnPickedUp(other.gameObject);
if (pickupSound)
SoundManager.PlayClip(pickupSound);
if (destroyOnPickup)
{
Destroy(gameObject);
}
}
}
protected abstract void OnPickedUp(GameObject receiver);
실체를 구현하기 위해 상속 받는다.
아이템을 먹었을 때, 체력이 회복되거나 스텟이 올라가도록 한다.
public class PickupStatModifiers : PickupItem
{
[SerializeField] private List<CharacterStats> statsModifier;
protected override void OnPickedUp(GameObject receiver)
{
CharacterStatsHandler statsHandler = receiver.GetComponent<CharacterStatsHandler>();
foreach (CharacterStats stat in statsModifier)
{
statsHandler.AddStatModifier(stat);
}
}
}
public class PickupHeal : PickupItem
{
[SerializeField] int healValue = 10;
private HealthSystem _healthSystem;
protected override void OnPickedUp(GameObject receiver)
{
_healthSystem = receiver.GetComponent<HealthSystem>();
_healthSystem.ChangeHealth(healValue);
}
}
GameManager에 5번째마다 아이템이 나오도록 추가한다.
public List<GameObject> rewards = new List<GameObject>();
// 생략
if (currentWaveIndex % 5 == 0)
{
CreateReward();
}
void CreateReward()
{
int idx = Random.Range(0, rewards.Count);
int posIdx = Random.Range(0, spawnPostions.Count);
GameObject obj = rewards[idx];
Instantiate(obj, spawnPostions[posIdx].position, Quaternion.identity);
}
'부트캠프 > Study' 카테고리의 다른 글
<Unity> 3D 게임 개발 심화 - RPG FSM(1) (2) | 2023.12.22 |
---|---|
<Unity> UI (0) | 2023.12.14 |
<Unity> 숙련 - 2D 게임 개발(7) (1) | 2023.12.12 |
<Unity> 숙련 - 2D 게임 개발(6) (1) | 2023.12.12 |
ToString() 메서드 (1) | 2023.12.11 |