■ 개요
○ 오늘 계획
- 데이터베이스 클래스 필드 -> 프로퍼티
- 코드 안정성 및 가독성 향상 -> 몬스터 스폰 함수 주석달기
- 스테이지 전환될때 플레이어 위치부터 초기화되어서 이상함-> 로드 순서 알아야할듯
■ CharacterManager 리팩토링
○ 플레이어 스폰 함수
/// <summary>
/// 플레이어를 동적 생성하는 함수입니다.
/// </summary>
public void SpawnPlayer()
{
if (Player == null)
{
Debug.Log("플레이어 생성");
GameObject playerObject = Instantiate(PlayerPrefab);
Player = playerObject.GetComponentInChildren<Player>();
Player.Init();
DontDestroyOnLoad(playerObject);
}
else
{
//Player.gameObject.SetActive(true);
Player.controller.enabled = false;
Player.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); // 초기 위치로 이동
Player.controller.enabled = true;
Player.controller.IdleStateInit();
PlayerPrefab.GetComponentInChildren<PlayerInputController>().InitializeCamera();
}
Managers.UI.Show<UIHUD>();
}
○ 몬스터 스폰 함수
/// <summary>
/// 몬스터를 생성해주는 함수 입니다.
/// </summary>
/// <param name="monsterIDs">현재 스테이지의 몬스터 ID 리스트</param>
/// <param name="monsterQuantity">현재 스테이지의 몬스터 수 리스트</param>
public void SpawnMonster(List<int> monsterIDs, List<int> monsterQuantity)
{
Dictionary<int, IObjectPool<Enemy>> curEnemyPool = new Dictionary<int, IObjectPool<Enemy>>(); // 현재 스테이지 에너미 풀을 저장할 딕셔너리
int listCount = monsterIDs.Count; // 데이터테이블 내 몬스터 종류 수
// 현재 스테이지의 몬스터 종류수 만큼 반복
for (int i = 0; i < listCount; i++)
{
InitMonsterPool(monsterIDs[i], monsterQuantity[i], curEnemyPool, i);
}
prevEnemyPool = new Dictionary<int, IObjectPool<Enemy>>(curEnemyPool); // 이전 에너미 풀을 현재 에너미 풀로 초기화
}
/// <summary>
/// 몬스터 종류별 에너미 풀을 초기화 하는 함수 입니다.
/// </summary>
/// <param name="monsterID">몬스터 ID</param>
/// <param name="quantity">몬스터 수</param>
/// <param name="curEnemyPool">현재 스테이지의 에너미 풀</param>
/// <param name="key">에너미 풀 딕셔너리 현재 인덱스(Key)</param>
private void InitMonsterPool(
int monsterID, int quantity, Dictionary<int, IObjectPool<Enemy>> curEnemyPool, int key)
{
var monsterPrefab = Managers.Resource.LoadAsset<Enemy>(Managers.Data.GameDataBase.MonsterDatas[monsterID]._prefabPath);
if (monsterPrefab == null) return;
curEnemyPool[key] = Managers.Pool.GetPool<Enemy>(monsterPrefab, quantity);
Managers.Game.enemyCount.Add(monsterID, quantity);
for (int j = 0; j < quantity; j++)
{
var enemy = curEnemyPool[key].Get(); // 에너미 풀에서 에너미 가져옴
enemy.SetPool(curEnemyPool[key]); // 에너미의 풀을 현재 풀로 초기화
//TODO : 몬스터 스탯 초기화
//TODO : 매직넘버 제거, Map 넓이에 비례하게 변경
enemy.SpawnTransformInit(monsterID, new Vector3(Random.Range(-5, 5), 0, Random.Range(-5, 5))); // 위치 초기화
}
}
■ StageManager 리팩토링
/// <summary>
/// 랜덤 스테이지 생성 후 층수에 맞는 강함을 지닌 몬스터를 소환하는 함수 입니다.
/// </summary>
/// <param name="floor">탑 층수</param>
public void CreateStage(int floor = 1)
{
Managers.Game.stageClear = false; // 스테이지 클리어 상태 초기화
//Managers.Character.SpawnPlayer();
StageType stageType = RandomStageType(floor);
int stageID = 0;
Logger.Log(stageType.ToString());
// 스테이지 특성에 맞는 몬스터 생성
switch (stageType)
{
case StageType.Boss:
stageID = RandomStageID<BossStageData>(Managers.Data.GameDataBase.BossStageDatas);
BossStageData bossStage = Managers.Data.GameDataBase.BossStageDatas[stageID];
Logger.Log(bossStage._name);
Managers.Character.SpawnMonster(bossStage._monsterIDs, bossStage._monsterQuantity);
break;
case StageType.Normal:
stageID = RandomStageID<NormalStageData>(Managers.Data.GameDataBase.NormalStageDatas);
NormalStageData normalStage = Managers.Data.GameDataBase.NormalStageDatas[stageID];
Logger.Log(normalStage._name);
Managers.Character.SpawnMonster(normalStage._monsterIDs, normalStage._monsterQuantity);
break;
case StageType.Event:
// 얘는 빼도 될듯. 그라운드 생성 고려 하여 일단 두기로 결정
break;
}
}
/// <summary>
/// 리스트에 저장된 스테이지타입을 랜덤으로 선택하여 ID(인덱스) 값을 반환하는 함수 입니다.
/// </summary>
/// <returns>랜덤 스테이지타입 ID</returns>
private StageType RandomStageType(int floor)
{
int stageType;
if (floor % BossStageInterval == 0)
{
stageType = 0; // 보스타입 고정
}
else
{
int stageCount = Managers.Data.GameDataBase.StageTypeDatas.Count; // 스테이지 종류 갯수 반환
//stageType = Random.Range(1, stageCount); // 보스방 빼고 랜덤 선택
stageType = 1;
}
return (StageType)stageType; // 이넘으로 변환
}
/// <summary>
/// 랜덤 스테이지 ID를 반환하는 함수 입니다.
/// </summary>
/// <typeparam name="T">해당 스테이지 데이터테이블</typeparam>
/// <param name="stageMonster">스테이지 딕셔너리</param>
/// <returns>스테이지 ID</returns>
private int RandomStageID<T>(Dictionary<int, T> stageMonster)
{
if (stageMonster == null || stageMonster.Count == 0)
{
Logger.WarningLog("stageMonster딕셔너리가 비어있습니다.");
}
List<int> keys = new List<int>(stageMonster.Keys);
// 딕셔너리에서 키 추출하여 리스트 만듬
int randomIndex = Random.Range(0, keys.Count);
// 키 리스트 카운트 범위내에서 랜덤 인덱스
return (int)keys[randomIndex];
}