XR플밍 - 12. UnityEngine3D Reactive 프로그래밍 - 기업협약 프로젝트 34일차 (10/2)

이형원·2일 전
0

XR플밍

목록 보기
213/215

1. 금일 한 업무 정리

  • 마법석 강화 시스템 구현 (약 60% 정도 완료)
    • 마법석 강화 데이터(레벨, 조각 정보) 추가
    • 마법석 강화 데이터 DB 반영을 위한 요소 추가
    • 마법석 가챠를 통한 조각 획득, DB 반영
    • 마법석 강화 UI 표시(팝업 패널은 아직)

2. 문제의 발생과 해결 과정

2.1 마법석 강화 데이터의 설정

마법석의 경우 캐릭터 시스템과는 다른 구석이 있기 떄문에 강화 데이터를 만드는 방법이 달라져야 한다고 생각했다.

  • 캐릭터는 Grade가 고정이며, 레벨 상승에 따라 스테이터스가 변하는 방식
  • 마법석의 경우에는 반면에 한 마법석이 3가지 Grade가 존재, 레벨 상승에 따라 희귀 마법석의 등장확률이 증가하는 매커니즘

하지만 현재 해당 요소를 고려하며 시스템을 구성하기에는 어려움이 있다고 판단했다.

현 상황에서 마법석 시스템의 구조 개편을 하기에는 어렵다고 판단하여, 가장 직관적인 방법으로 3가지 등급의 마법석이 모두 동일한 레벨업 데이터, 레벨과 조각 요소 및 확률을 들고 있는 방식으로 설계하기로 결정했다.

여기서 업그레이드 데이터의 경우, 완전히 새로 만드는 것이 아닌 캐릭터 업그레이드 데이터에서 만든 것을 활용하여 마법석 시스템에 맞게 추가했다.

using Firebase.Database;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;

[CreateAssetMenu(fileName = "MagicStone_UpgradeMagicStoneData", menuName = "Data/Upgrade/MagicStone_UpgradeMagicStoneData")]
public class MagicStoneUpgradeData : ScriptableObject
{
    private SubGrade _grade;
    private MagicStoneLevelUpData _levelUpData;

    public CurrentUpgradeData CurrentUpgradeData;

    public event Action OnLevelUp;

    public void Init(SubGrade grade, MagicStoneLevelUpData data)
    {
        _grade = grade;
        _levelUpData = data;
    }

    public int GetRequiredPiece()
    {
        if (CurrentUpgradeData.UpgradeLevel >= 10 ||
            CurrentUpgradeData.UpgradeLevel <= 0) return 0;

        if (_levelUpData == null)
        {
            Debug.LogError($"[{name}] LevelUpData가 설정되지 않았습니다.");
            return 0;
        }

        PieceLevelRatio pieceLevelRatio = _levelUpData.LevelRatio.Find(l => l.Level == CurrentUpgradeData.UpgradeLevel + 1);
        if (pieceLevelRatio == null)
        {
            Debug.LogError($"[{name}] {_grade} / {CurrentUpgradeData.UpgradeLevel}에 맞는 PieceLevelRatio 데이터가 없습니다.");
            return 0;
        }

        return pieceLevelRatio.RequirePiece;
    }

    public int GetRequiredGold()
    {
        if (CurrentUpgradeData.UpgradeLevel >= 10 ||
            CurrentUpgradeData.UpgradeLevel <= 0) return 0;

        if (_levelUpData == null)
        {
            Debug.LogError($"[{name}] LevelUpData가 설정되지 않았습니다.");
            return 0;
        }

        PieceLevelRatio pieceLevelRatio = _levelUpData.LevelRatio.Find(l => l.Level == CurrentUpgradeData.UpgradeLevel + 1);
        if (pieceLevelRatio == null)
        {
            Debug.LogError($"[{name}] {_grade} / {CurrentUpgradeData.UpgradeLevel}에 맞는 PieceLevelRatio 데이터가 없습니다.");
            return 0;
        }

        return pieceLevelRatio.RequireGold;
    }

    public void AddPiece(int piece)
    {
        CurrentUpgradeData.CurrentPieces += piece;
    }

    public async Task<bool> LevelUpWithPieces()
    {
        if (CurrentUpgradeData.UpgradeLevel >= 10) return false;

        if (CurrentUpgradeData.UpgradeLevel <= 0)
        {
            if (CurrentUpgradeData.CurrentPieces >= 5)
            {
                CurrentUpgradeData.CurrentPieces -= 5;
                CurrentUpgradeData.UpgradeLevel += 1;
                return true;
            }
            else
            {
                if (PopupManager.Instance != null)
                {
                    PopupManager.instance.ShowPopup("조각이 부족합니다.");
                }
                return false;
            }
        }
        else if (CurrentUpgradeData.UpgradeLevel >= 1)
        {
            int requiredPiece = GetRequiredPiece();
            int requiredGold = GetRequiredGold();

            // 골드, 조각 체크
            string uid = FirebaseManager.Auth.CurrentUser.UserId;
            var goldRef = FirebaseManager.DataReference.Child("UserData").Child(uid).Child("Gold");
            DataSnapshot snapshot = await goldRef.GetValueAsync();
            int currentGold = snapshot.Exists ? Convert.ToInt32(snapshot.Value) : 0;

            if (CurrentUpgradeData.CurrentPieces >= requiredPiece && currentGold >= requiredGold)
            {
                CurrentUpgradeData.CurrentPieces -= requiredPiece;
                CurrentUpgradeData.UpgradeLevel += 1;

                await DBManager.Instance.SubtractGoldAsync(requiredGold);
                OnLevelUp?.Invoke();
                return true;
            }
        }
        return false;
    }
}

[CreateAssetMenu(fileName = "MagicStone_LevelUpData", menuName = "Data/Temp/MagicStone_LevelUpData")]
public class MagicStoneLevelUpData : ScriptableObject
{
    public List<PieceLevelRatio> LevelRatio = new List<PieceLevelRatio>();

    public int GetCumulativePiece(int level)
    {
        int cumulativePiece = 0;

        int index = level - 1;
        if (index < 0)
        {
            index = 0;
            cumulativePiece += 10;
        }

        for (int i = index; i < LevelRatio.Count; i++)
        {
            cumulativePiece += LevelRatio[i].RequirePiece;
        }
        Debug.Log(cumulativePiece);

        return cumulativePiece;
    }
}

2.2 Project Setting 충돌로 인한 오류

다른 팀원이 작업한 작업물을 Pull하고 나니 이런 오류가 발생했다.

Modern UI Pack 이라는 에셋에서 오류가 발생하는 현상인데, 갑작스레 오류가 발생할 만한 이유가 없었다.

이에 대한 원인을 찾아보던 중, 원인이 발생하는 이유가 Project Setting이 반영이 안 되서 발생하는 문제임을 알게 되었다.

Active Input Handling이 설정되어 있지 않아 발생한 문제였으며, Both로 설정하고 나니 오류가 해결되었다.

3. 개선점 및 과제

3.1 마법석 강화 시스템 완성

3.2 게임 시스템 전체적 마무리 작업 - 증강 시스템 점검

3.3 UI 폴리싱

3.4 리팩토링

profile
게임 만들러 코딩 공부중

0개의 댓글