강화 재료와 비용 계산 구조

목차

1. 시스템 요구 사항

강화 대상 선택과 UI 동기화 구조를 정리한 이후, 다음으로 해결해야 했던 문제는 강화 단계와 장비 타입에 따라 재료와 비용을 어떻게 계산할 것인가였다.

강화 단계가 올라갈수록 비용은 자연스럽게 증가해야 했고, 무기와 반지처럼 장비 성격이 다른 아이템들은 서로 다른 강화 한계와 비용 구조를 가져야 했다.

또한 강화 비용 계산 결과는 UI 표시, 버튼 활성화 여부, 경고 메시지 출력과 직접적으로 연결되기 때문에 계산 로직과 UI 출력이 섞이지 않는 구조가 필요했다.

즉, 단순히 수치를 계산하는 문제가 아니라, 강화 규칙이 늘어나더라도 구조가 무너지지 않는 비용 계산 흐름 구조 설계가 필요했다.

2. 설계  목표

- 강화 단계에 비례하여 비용이 점진적으로 증가할 것

- 장비 타입별로 강화 한계와 비용 배율을 분리할 것

- 계산 로직과 UI 출력 로직을 명확히 분리할 것

- 재료 부족 / 강화 불가 상태를 UI에서 즉시 인식 가능하게 할 것

- 이후 강화 규칙 추가 시 기존 구조를 그대로 확장할 수 있을 것

3. 흐름도

강화 재료와 비용 계산은 선택된 아이템의 상태를 기준으로 매 프레임 갱신되도록 구성하였다.

이 흐름을 통해 강화 규칙 변경, 재화 변화, 아이템 변경 상황에서도 UI와 로직이 항상 같은 기준으로 동기화되도록 했다.

4. 구현

위 표는 강화 단계와 장비 타입에 따라강화 재료와 비용이 어떻게 증가하도록 설계했는지를 정리한 것이다.

이 구조를 기준으로 강화 비용 계산 로직을 구현하였다.

4.1. 장비 타입에 따른 강화 규칙 분기

강화 비용과 강화 한계는 장비 타입에 따라 다르게 적용된다.

이를 위해 이 단계에서는 강화 대상이 어떤 장비 타입인지 판단하는 역할만 수행하도록 분리하였다.

private void UpdateRequirementsByType()
{
    if (selectedItem.equipType == Item.EquipType.Weapon)
    {
        SetAccordingToType(1, 10);  // 무기: 비용 배율 1, 최대 강화 10
    }
    else
    {
        SetAccordingToType(2, 3);   // 예: 반지: 비용 배율 2, 최대 강화 3
    }
}

UpdateRequirementsByType() 함수는 장비 타입에 따라 강화 규칙이 달라질 수 있다는 점을 고려해,

실제 강화 비용 계산을 직접 수행하지 않고 비용 배율과 최대 강화 단계만 결정하여 다음 단계로 전달한다.

이 구조를 통해 장비 타입이 추가되더라도 기존 비용 계산 로직을 수정할 필요 없이 해당 타입에 맞는 규칙만 추가하면 되도록 설계하였다.

즉, 장비 타입 확장에 대비한 규칙 분기 전용 단계로서의 역할을 가진다.

4.2. 강화 단계 기반 비용 계산

실제 강화 재료와 재화 계산은 강화 단계와 장비 타입에 따른 배율을 기준으로 수행된다.

private void SetAccordingToType(int x, int maxGrade)
{
    requiredCoin = (selectedItem.grade + 1) * 400 * x;
    requiredCrystal = (selectedItem.grade + 1) * x;

    if (selectedItem.grade < maxGrade)
    {
        upgradeInfo.text = $"{selectedItem.grade}  >  {selectedItem.grade + 1}";
        crystalCount.text = $"{currentCrystalCount} / {requiredCrystal}";
        reqCoin.text = $"필요 재화: {requiredCoin}";
    }
    else
    {
        upgradeInfo.text = "최대 강화";
        crystalCount.text = "-";
        reqCoin.text = "필요 재화: -";
    }
}

강화 비용 계산은 SetAccordingToType() 함수 하나로 통합하여 처리한다.

장비 타입에 따라 비용 배율과 최대 강화 단계를 매개변수로 전달받아 계산하도록 설계하였다.

강화 비용은 (현재 강화 단계 + 1)을 곱셈 인자로 사용해, 강화 단계가 높을수록 자연스럽게 비용이 증가하도록 구성하였다.

이를 통해 초반 강화는 부담이 적고, 후반 강화는 전략적 선택이 되도록 유도하였다.

현재 강화 단계가 최대 강화 단계보다 낮을 경우에는 다음 강화 단계, 필요 재화, 필요 크리스탈 수량을 UI에 즉시 출력한다.

최대 강화 단계에 도달한 경우에는 강화가 불가능한 상태임을 명확히 전달하기 위해, 필요 재화 UI를 ‘-’로 표시하고, 강화 정보 텍스트를 ‘최대 강화’ 로 출력한다.

이를 통해 추가적인 안내 없이도 플레이어가 상태를 직관적으로 인지할 수 있도록 설계하였다.

4.3. 강화 가능 여부 판단

비용 계산 이후에는 현재 보유 재화와 비교하여 강화 가능 여부를 판단한다.

private void UpdateUpgradeState()
{
    if (upgradeInfo.text == "최대 강화")
    {
        BtnOrErr(false, false);
        return;
    }

    bool hasEnoughCrystal = currentCrystalCount >= requiredCrystal;
    bool hasEnoughCoin = itemManager.coin >= requiredCoin;

    if (hasEnoughCrystal && hasEnoughCoin)
        BtnOrErr(true, false);
    else
        BtnOrErr(false, true);
}

비용 계산 이후에는 현재 강화 시도가 가능한 상태인지 판단하는 단계가 필요하다.

UpdateUpgradeState() 함수는 강화 비용 계산 결과와 현재 보유 재화를 비교하여, 강화 가능 여부만 판단하는 역할을 수행한다.

먼저 최대 강화 상태를 가장 우선적으로 차단하여, 이미 강화가 불가능한 경우에는 불필요한 재화 비교가 이루어지지 않도록 했다.

이후에는 크리스탈과 재화를 각각 비교하여 두 조건이 모두 충족될 경우에만 강화 가능 상태로 판단한다.

이 판단 결과는 UI에 직접 반영되지 않고, 다음 단계의 UI 제어 함수로 전달된다.

이를 통해 강화 조건이 변경되거나 재화 종류가 추가되더라도, 판단 로직과 UI 로직이 서로 영향을 주지 않도록 구조를 분리하였다.

현재는 빠른 구현을 위해 UI 텍스트를 기준으로 판단했으며, 이후에는 강화 상태 enum으로 분리할 수 생각이다.

4.4. 버튼과 경고 UI 제어

강화 버튼과 경고 메시지는 강화 가능 여부 판단 결과만을 전달받아 처리한다.

public void BtnOrErr(bool btn, bool err)
{
    upgradeBtn.SetActive(btn);
    warningText.SetActive(err);
}

강화 버튼과 경고 메시지는 강화 가능 여부 판단 결과만을 전달받아 처리한다.

이 함수는 전달받은 결과에 따라, 각각에 맞는 UI 요소를 활성화 또는 비활성화한다.

이러한 분리를 통해 UI 구조가 변경되거나 버튼 디자인이 수정되더라도 강화 계산 로직에는 전혀 영향을 주지 않는 구조를 유지할 수 있었다.

5. 개발 의도

처음에는 강화 비용 계산과 UI 출력을 한 함수에서 처리하는 방식도 고려했다.

하지만 이 경우 강화 규칙이 늘어날수록 조건문이 증가하고 UI 수정이 곧 로직 수정으로 이어질 가능성이 컸다.

따라서, 장비 타입 판단, 비용 계산, 강화 가능 여부 판단, UI 출력을 단계별로 분리한 구조를 선택했다.

이 구조를 통해 강화 단계 조정, 장비 타입 추가, 밸런스 변경이 발생하더라도 기존 구조를 유지한 채 확장이 가능해졌고, UI 변경에도 영향을 받지 않는 강화 비용 계산 구조를 확보할 수 있었다.