기존에는 TakeReward라는 클래스를 통해 적을 처치했을 때 드랍되는 아이템 보상을 관리하고 있었습니다.
해당 구조는 단순한 보상 지급만을 처리하는 형태였기 때문에 다음과 같은 문제점이 있었습니다:

  • 보상 아이템의 수량이 고정(항상 1개) 으로 처리됨
  • 경험치 보상을 아이템으로 나눠주는 기능이 없음
  • 향후 기능을 추가하거나 확장할 때 기존 구조 전체를 수정해야 하는 부담

이전에 사용한 구조가 궁금하신 분들은 아래 글을 참고하시면 됩니다.
👉 이전 보상 시스템 구조

 

[Unity] 보상 드롭 시스템 및 UI 구현

이번 프로젝트에서는 유니티 기반의 게임에서 몬스터 처치 후 발생하는 보상 아이템을 드롭 테이블 기반으로 계산하고, UI에 시각적으로 표현하는 기능을 구현하였습니다.보상 드롭 로직은 기

danpat77.tistory.com


1. 구현 목표 및 개요

이번 리팩토링에서는 다음과 같은 점을 중심으로 구조를 개선했습니다:

  • 보상 아이템의 수량을 자유롭게 지정할 수 있도록 변경
  • 경험치 수치를 기반으로 경험치 아이템을 자동으로 계산하여 보상
  • 기존의 드롭 테이블 기반 구조는 그대로 유지하면서 기능만 확장
  • UI 연동 방식은 그대로 유지해, 시스템 변경 없이 연결 가능

2. 리팩토링 전후 코드 비교

AddItem 메서드 구조

🔸 리팩토링 전 (TakeReward 클래스)

private void AddItem(int item)
{
    ItemData itemData = GameManager.Instance.Player.inventory.items[item].data;
    if (rewardList.ContainsKey(item))
    {
        rewardList[item].amount++;
    }
    else
    {
        rewardList.Add(item, new RewardItem { ItemData = itemData, amount = 1 });
    }
}

 

🔸 리팩토링 후 (RewardSystem 클래스)

private void AddItem(int item, int amount)
{
    ItemData itemData = GameManager.Instance.Player.inventory.items[item].data;
    if (rewardList.ContainsKey(item))
    {
        rewardList[item].amount += amount;
    }
    else
    {
        rewardList.Add(item, new RewardItem { ItemData = itemData, amount = amount });
    }
}

차이점 :
수량을 직접 지정할 수 있도록 amount 매개변수를 추가해
다양한 보상 케이스에 유연하게 대응할 수 있게 되었습니다.

 


경험치 보상 기능 추가

public void TakeExpItem(int exp)
{
    Dictionary<int, int> expItemDict = ExpItemCal(exp);

    foreach (var pair in expItemDict)
    {
        AddItem(pair.Key, pair.Value);
    }
}

경험치 수치를 입력하면, 자동으로 적절한 경험치 아이템으로 환산해 보상 리스트에 추가해줍니다.
반복되는 코드 없이 깔끔하게 경험치 보상을 처리할 수 있게 되었어요.


경험치 분배 알고리즘

public Dictionary<int, int> ExpItemCal(int exp)
{
    Dictionary<int, int> expItems = new Dictionary<int, int>();
    int[] expValues = { 250, 100, 50, 20 };
    int[] itemKeys = { 9103, 9102, 9101, 9100 };

    for (int i = 0; i < expValues.Length; i++)
    {
        int count = exp / expValues[i];
        if (count > 0)
        {
            expItems[itemKeys[i]] = count;
            exp %= expValues[i];
        }
    }

    if (exp > 0)
    {
        if (expItems.ContainsKey(9100))
            expItems[9100] += 1;
        else
            expItems[9100] = 1;
    }

    return expItems;
}

기능 설명:

  • 경험치를 큰 단위부터 순차적으로 나누어 아이템화
  • 남은 경험치는 무조건 20짜리 경험치 아이템(9100) 1개로 처리
  • 잔여 경험치도 버려지지 않도록 100% 보상 처리 가능

 


3. 마무리

이번 리팩토링에서는 단순히 코드를 정리하는 데 그치지 않고,
앞으로 다양한 보상 시스템을 추가할 수 있는 확장성까지 고려해 구조를 다듬었습니다.

특히 경험치 보상과 수량 지정 기능이 추가되면서
전투 외에도 퀘스트 보상, 이벤트 보상, 성장 보상 등 다양한 영역에서도 재활용 가능해졌다는 점이 가장 만족스러웠습니다.

앞으로도 기능을 설계할 때는 "확장 가능성" 을 항상 염두에 두고 시작해야겠다는 생각이 들었던 작업이었습니다

+ Recent posts