강화 재료와 비용 계산 구조
목차
1. 시스템 요구 사항
강화 대상 선택과 UI 동기화 구조를 정리한 이후, 강화 단계와 장비 타입에 따라 재료와 비용을 일관되게 계산하는 구조가 필요했다.
강화 단계가 올라갈수록 비용은 자연스럽게 증가해야 했고, 무기와 반지처럼 장비 성격이 다른 아이템들은 서로 다른 강화 한계와 비용 구조를 가져야 했다.
또한 강화 비용 계산 결과는 UI 표시, 버튼 활성화 여부, 경고 메시지 출력과 직접적으로 연결되기 때문에 계산 로직과 UI 출력이 섞이지 않는 구조가 필요했다.
즉, 단순히 수치를 계산하는 문제가 아니라, 강화 규칙이 늘어나더라도 구조가 무너지지 않는 비용 계산 흐름 구조 설계가 필요했다.
2. 설계 목표
- 강화 단계에 비례하여 비용이 점진적으로 증가할 것
- 장비 타입별로 강화 한계와 비용 배율을 분리할 것
- 계산 로직과 UI 출력 로직을 명확히 분리할 것
- 재료 부족 / 강화 불가 상태를 UI에서 즉시 인식 가능하게 할 것
- 이후 강화 규칙 추가 시 기존 구조를 그대로 확장할 수 있을 것
3. 흐름도

강화 비용과 강화 가능 여부 판단은 Update 루프 내에서selectedItem이 존재할 경우에만 실행되며, 현재 강화 단계(selectedItem.grade)와 보유 재화 상태를 기준으로매 프레임 동일한 계산 흐름을 거치도록 구성하였다.
이 흐름을 통해 강화 규칙 변경, 재화 변화, 아이템 변경 상황에서도 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 함수에서는 선택된 아이템의 equipType을 기준으로 비용 배율과 최대 강화 단계를 결정한다.
이 함수는 무기, 반지 등 장비 타입에 따라 서로 다른 강화 규칙이 적용될 수 있다는 점을 고려하여, 실제 비용 계산을 수행하지 않고 필요한 규칙 정보만을 다음 단계로 전달한다.
이때 결정된 비용 배율(x)과 최대 강화 단계(maxGrade)는 매개변수 형태로 SetAccordingToType 함수에 전달되며, 이를 통해 장비 타입 판단과 실제 강화 비용 계산 로직이 코드 레벨에서 분리된다.
장비 타입이 추가되더라도 이 단계에 규칙만 추가하면 되도록 구조를 유지하였다.
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 함수에서 수행된다.
이 함수는 현재 강화 단계와 전달받은 비용 배율을 기준으로 requiredCoin과 requiredCrystal 값을 계산한다.
강화 비용은 (현재 강화 단계 + 1)을 곱셈 인자로 사용하여, 강화 단계가 증가할수록 비용이 자연스럽게 증가하도록 구성하였다.
이를 통해 초반 강화는 부담이 적고, 후반 강화는 전략적 선택이 되도록 유도하였다.
현재 강화 단계가 최대 강화 단계보다 낮은 경우에는 다음 강화 단계, 필요 재화, 필요 크리스탈 수량을 UI에 즉시 반영한다.
반대로 최대 강화 단계에 도달한 경우에는 강화가 불가능한 상태임을 명확히 전달하기 위해 강화 정보 텍스트를 ‘최대 강화’로 표시하고, 필요 재화 관련 UI를 ‘-’로 처리한다.
이 단계에서 계산된 requiredCoin과 requiredCrystal은 이후 UpdateUpgradeState 함수에서 현재 보유 재화와 비교하는 기준 값으로 사용된다.
이를 통해 비용 계산 단계와 강화 가능 여부 판단 단계가 변수 공유를 통해 자연스럽게 연결된다.
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 함수에서 강화 시도가 가능한 상태인지 판단한다.
UpdateUpgradeState 함수는 강화 비용 계산 결과와 현재 보유 재화를 비교하여, 강화 가능 여부만 판단하는 역할을 수행한다.
이 함수는 먼저 최대 강화 상태를 우선적으로 차단하여 이미 강화가 불가능한 경우 불필요한 재화 비교가 이루어지지 않도록 한다.
이후 크리스탈과 재화를 각각 비교하여 두 조건이 모두 충족될 경우에만 강화 가능 상태로 판단한다.
판단 결과는 boolean 값으로 변환되어 강화 버튼과 경고 UI를 제어하는 BtnOrErr 함수로 즉시 전달된다.
이를 통해 강화 가능 여부 판단 로직과 UI 제어 로직을 분리하고, 재화 종류나 강화 조건이 변경되더라도 구조가 서로 영향을 주지 않도록 구성하였다.
현재 구현에서는 최대 강화 상태 판단을 위해 강화 단계 UI 텍스트를 기준으로 처리하고 있으며, 이후 강화 상태를 enum 기반으로 분리할 수 있도록 구조를 열어두었다.
4.4. 버튼과 경고 UI 제어
public void BtnOrErr(bool btn, bool err)
{
upgradeBtn.SetActive(btn);
warningText.SetActive(err);
}
BtnOrErr 함수는 전달받은 판단 결과에 따라 강화 버튼과 경고 메시지를 활성화 또는 비활성화한다.
이 함수는 UI 제어만을 담당하며, 강화 비용 계산이나 조건 판단 로직과는 분리되어 있다.
이를 통해 UI 구조 변경이나 버튼 디자인 수정이 발생하더라도강화 계산 로직에는 영향을 주지 않는 구조를 유지할 수 있었다.
5. 개발 의도
처음에는 강화 비용 계산과 UI 출력을 한 함수에서 처리하는 방식도 고려했다.
하지만 이 경우 강화 규칙이 늘어날수록 조건문이 증가하고 UI 수정이 곧 로직 수정으로 이어질 가능성이 컸다.
따라서, 장비 타입 판단, 비용 계산, 강화 가능 여부 판단, UI 출력을 단계별로 분리한 구조를 선택했다.
이 구조를 통해 강화 단계 조정, 장비 타입 추가, 밸런스 변경이 발생하더라도 기존 구조를 유지한 채 확장이 가능해졌고, UI 변경에도 영향을 받지 않는 강화 비용 계산 구조를 확보할 수 있었다.
