TIL (79) | 2023.11.16 | SpawnPoint

kjg5370·2023년 11월 16일
0

TIL

목록 보기
77/91
post-thumbnail

들어가기 앞서

저희 게임은 플레이어가 클리어 해야하는 구간이 있고
그 구간 안의 일정 수의 적을 잡아야 다음 구간이 열리는 구조입니다.
이때 적을 특정 위치에서 생성을 해주는 데
원래는 씬 뷰에서 임시적으로 직접 빈 오브젝트를 만들어 그 위치에서 생성되게 하였는데
매번 씬뷰에 직접 위치를 지정해주는게 너무 힘들어서
이 위치 데이터를 스크립터블 오브젝트의 형태로 저장해서 사용하는 방식으로 바꿨습니다.

오늘 배운 것

  • 위치데이터
    적이 소환될 위치나 엘리트 몬스터의 움직임에 쓸 위치데이터를 스크립터블 오브젝트로 만들었습니다.
    [CreateAssetMenu(fileName = "TargetPositionData", menuName = "Custom/TargetPositionData", order = 1)]
    public class TargetPositionData : ScriptableObject
    {
        public List<Vector3> targetPositions = new List<Vector3>();
    }
  • EnemySpawner
    위의 스크립터블 오브젝트의 위치데이터를 기반으로 적을 소환할 spawner를 만듭니다.
      public class EnemySpawner : MonoBehaviour
    {
        [Header("Position Data")]
        public TargetPositionData positionData; // 위치 데이터 스크립터블 오브젝트
    
        public GameObject spawnEnemy;
    
        public List<GameObject> SpawnEnemies()
        {
            List<GameObject> enemies = new List<GameObject>();
    
            foreach (Vector3 position in positionData.targetPositions)
            {
                GameObject enemy = Instantiate(spawnEnemy, position, Quaternion.identity);
                enemy.transform.SetParent(this.transform);
                enemies.Add(enemy);
            }
    
            return enemies;
        }
    }
  • Sector에 SpawnEnemies를 호출하여 적이 생성되고 적을 죽이면 구간이 클리어하는 로직을 만듭니다.
  1. 적 스폰
      // 한 웨이브 적 스폰
        protected void SpawnWaveEnemy()
        {
            if (currentWave < waves.Count)
            {
                for (int i = 0; i < waves.Count; i++)
                {
                    foreach (EnemySpawner spawner in waves[i])
                    {
                        List<GameObject> spawnedEnemies = spawner.SpawnEnemies();
    
                        foreach (GameObject enemyObject in spawnedEnemies)
                        {
                            Health enemyHealth = enemyObject.GetComponent<Health>();
                            enemyHealth.OnDie += OnEnemyDied;
                            enemyCount++;
                        }
                    }
                }
            }
        }
  2. OnEnemyDied
    적이 죽었을 때 실행될 함수
          public void OnEnemyDied()
        {
            enemyCount--;
    
            if (enemyCount == 0)
            {
                CheckWaveClear();
            }
        }
  3. 웨이브 클리어
       // 웨이브 클리어 여부 확인
        protected void CheckWaveClear()
        {
            enemyCount = 0;
            currentWave++;
    
            if (sectorCount < sectorDataList.Count)
            {
                if (currentWave >= waves.Count)
                {
                    if (sectorDataList[sectorCount].hasEvent)
                    {
                        //sectorDataList[sectorCount].eventScenario.StartEventMode();
                        waitUntil = new WaitUntil(() => sectorDataList[sectorCount].eventScenario.isClear);
                        StartCoroutine(WaitForEvent());
                    }
                    else
                    {
                        OnClearSector();
                        currentWave = 0;
                        sectorCount++;
                        nextSector();
                    }
                }
                else
                {
                    StartNextWave();
                }
            }
        }
  • 결과

    이런식으로 원하는 만큼의 적을 소환할 수 있습니다.

진행 사항

  • enemyspawner 구조 변경
    • 위치데이터를 스크립터블 오브젝트를 활용
profile
학생입니다

0개의 댓글