내일배움캠프 54일차 TIL : 매니저 리팩토링

woollim·2024년 12월 9일
0

내일배움캠프TIL

목록 보기
47/65
post-thumbnail

■ 개요

○ 오늘 계획

  • 데이터베이스 클래스 필드 -> 프로퍼티
  • 코드 안정성 및 가독성 향상 -> 몬스터 스폰 함수 주석달기
  • 스테이지 전환될때 플레이어 위치부터 초기화되어서 이상함-> 로드 순서 알아야할듯


■ 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];
}

0개의 댓글