내일배움캠프 71일차 TIL : 로그인타이틀, 전투스테이지 페이즈 구현

woollim·4일 전
0

내일배움캠프TIL

목록 보기
64/65
post-thumbnail

■ 개요

○ 오늘 계획

  • 저장기능
    • 고장난 로그인 수정
  • 전투 스테이지 변경
    • 노말 - 페이즈 구분
  • 노피격 보너스 명성치 점수


■ 로그인타이틀

○ 디자인 변경

  • 기존 디자인
    [게임 타이틀]

    [이름 생성]


  • 변경 디자인
    [게임 타이틀]

    [이름 생성]


○ 저장 데이터 확인

  • 저장된 데이터가 있다면 바로 시작
  • 없다면 이름 생성 후 시작
    private void OnStartButtonClick()
    {
        Managers.Sound.PlaySFX(SFX.UI_ButtonClick);
        mainMenuGroup.interactable = false;

        if(Managers.SaveLoad.FileExists())
        { // 저장파일이 있으면, 게임시작
            mainMenuGroup.DOFade(0f, fadeOutDuration)
    .OnComplete(() => OnGameStartRequested?.Invoke());
        }
        else
        { // 없으면 로그인 화면으로
            mainMenuGroup.DOFade(0f, fadeOutDuration)
    .OnComplete(() => OnLoginRequested?.Invoke());
        }
    }


■ 전투스테이지 페이즈 구현

○ 변경전

  • 1회만 10마리의 몬스터가 소환
  • 여러 종류의 몬스터 or 단일 몬스터 소환
  • (사진에서 페이즈 수는 제외하고 봐야함)


○ 변경후

  • 1페이즈 당 10~20 마리의 몬스터가 소환
  • 페이즈 수에 맞춰서 나뉘어서 소환
  • 1페이즈당 같은 종류의 몬스터가 나오고, 다음 페이즈에선 다른 종류의 몬스터가 나온다
  • 이유: 이전에 각기 다른 종류의 몬스터가 섞여 나왔을때 시각적으로 지저분해 보였음. 이속이 다 다르기 때문에 몰이 사냥하기 불편했음.


○ 프로젝트 코드

  • StageManager
    • 매개 변수 전달을 없앰. 싱글톤이기 때문에 매개변수 전달 없이 바로 사용가능.
    • 이편이 좀더 함수를 자유롭게 쓸 수 있음.
    • ex) 스폰 노말 몬스터 함수를 다른곳에서 페이즈 별로 호출 가능
    /// <summary>
    /// 스테이지 ID 에 맞는 몬스터를 소환해주는 함수 입니다
    /// </summary>
    public void EnterStageMonsterSpawn()
    {
        switch (StageType)
        {
            case StageType.Boss:
                Managers.Character.SpawnBossMonster();
                break;
            case StageType.Normal:
                Managers.Character.SpawnNormalMonster();
                break;
        }
    }
  • CharacterManager
    • 보스 몬스터는 기존 방법대로 소환
    • 노말 몬스터 소환 함수를 따로 분리하여 페이즈별로 소환하도록 변경
/// <summary>
/// 보스 몬스터를 생성해주는 함수 입니다.
/// </summary>
public void SpawnBossMonster()
{
    BossStageData bossStage = Managers.Data.GameDataBase.BossStageDatas[Managers.Stage.StageID];
    int listCount = bossStage._monsterIDs.Count; // 데이터테이블 내 몬스터 종류 수

    // 현재 스테이지의 몬스터 종류수 만큼 반복
    for (int i = 0; i < listCount; i++)
    {
        InitMonsterPool(bossStage._monsterIDs[i], bossStage._monsterQuantity[i]);
    }
}

/// <summary>
/// 노말 몬스터를 생성해주는 함수 입니다.
/// </summary>
public void SpawnNormalMonster()
{
    NormalStageData normalStage = Managers.Data.GameDataBase.NormalStageDatas[Managers.Stage.StageID];
    int currentPhase = Managers.Game.CurrentMonsterPhase; // 데이터테이블 내 몬스터 종류 수

    Logger.Log($"현재 페이즈 : {currentPhase}, 맥스 페이즈 : {normalStage._phaseCount}");
    if (currentPhase < normalStage._phaseCount)
    {
        InitMonsterPool(normalStage._monsterIDs[currentPhase], normalStage._monsterQuantity[currentPhase]);
    }
}

/// <summary>
/// 몬스터 종류별 에너미 풀을 초기화 하는 함수 입니다.
/// </summary>
/// <param name="monsterID">몬스터 ID</param>
/// <param name="quantity">몬스터 수</param>
private void InitMonsterPool(int monsterID, int quantity)
{
    var monsterPrefab = Managers.Resource.LoadAsset<Enemy>(Managers.Data.GameDataBase.MonsterDatas[monsterID]._prefabPath);
    if (monsterPrefab == null) return;

    if(!enemyPool.ContainsKey(monsterID))
    {
        enemyPool.Add(monsterID, Managers.Pool.GetPool<Enemy>(monsterPrefab, quantity));
    }

    Managers.Game.AddEnemyCount(monsterID, quantity);

    for (int j = 0; j < quantity; j++)
    {
        var enemy = enemyPool[monsterID].Get(); // 에너미 풀에서 에너미 가져옴
        enemy.SetMonster(monsterID);
    }
}
  • GameManager
    • 페이즈 변수와, 마지막 소환된 몬스터ID 변수 추가
    • 해당 페이즈 몬스터의 절반이 풀에 반납되면 다음 페이즈 몬스터들 소환
public class GameManager : MonoBehaviour, IManager
{
    private Dictionary<int, int> stageEnemyCount; // 해당 스테이지에 있는 에너미 카운트
    public int CurrentMonsterPhase { get; private set; } // 노말 스테이지 몬스터 현재 페이즈
    public int LastSpawnMonsterID { get; private set; } // 마지막에 소환된 몬스터의 ID
    
        public void SubEnemyCount(int monsterID, Enemy enemy)
    {
        // 딕셔너리에서 monsterID를 키로 해당되는 밸류(몬스터 수)를 찾습니다.
        if (!stageEnemyCount.TryGetValue(monsterID, out int monsterCount))
            return;

        TopReputeScore += enemy.Stat.ReputeNumber;
        stageEnemyCount[monsterID]--;

        if (Managers.Stage.StageType == StageType.Normal && LastSpawnMonsterID != monsterID)
        {
            // 마지막 페이즈가 아니고, 페이즈 별 몬스터 절반이 죽었을 경우에
            if (CurrentMonsterPhase < Managers.Data.GameDataBase.NormalStageDatas[Managers.Stage.StageID]._phaseCount - 1 && stageEnemyCount[monsterID] < Managers.Data.GameDataBase.NormalStageDatas[Managers.Stage.StageID]._monsterQuantity[CurrentMonsterPhase] / 2)
            {
                CurrentMonsterPhase++; // 현재 페이즈 증가
                LastSpawnMonsterID = monsterID;
                // 다음 페이즈 몬스터 소환
                Managers.Character.SpawnNormalMonster();
                Logger.Log($"{CurrentMonsterPhase}페이즈 시작");
            }
        }

        if (stageEnemyCount[monsterID] <= 0) // 다 죽였다면
        {
            stageEnemyCount.Remove(monsterID);
            if (stageEnemyCount.Count == 0) // 모든 종류의 몬스터가 죽었다면
            {
                StageClear(enemy.gameObject.transform.position);
            }
        }
    }
}

0개의 댓글