속성 상태 기준 비용 계산 및 UI 동기화 구조

목차

1. 요구 사항

2. 설계 목표

3. 흐름도

4. 구현

        4.1. 최대 속성 상태 통합 관리

       4.2. 보유 재료 UI 갱신 구조

       4.3. 속성 단계 기반 비용 계산 및 UI 출력

5. 개발 의도

1. 시스템 요구 사항

속성 부여 시스템의 두 번째 문제는 아이템의 현재 속성 상태에 따라 비용 UI와 입력 가능 상태가 항상 정확히 동기화되는가였다.

속성 부여는 단순히 재료를 소모하는 기능이 아니라, 현재 부여된 속성의 개수, 최대 속성 도달 여부, 그리고 추가 시도가 가능한 상태인지에 따라 UI와 입력 가능 여부가 즉시 달라져야 하는 시스템이다.

특히 속성 시스템은 강화 시스템과 달리 동일 아이템에 대해 여러 번 반복적으로 접근하며 상태가 누적되는 구조이기 때문에, 한 번의 계산 결과를 저장해두는 방식보다는 항상 현재 상태를 기준으로 판단하는 구조가 필요했다.

이 구조를 사용하지 않을 경우, 속성 결과가 반영된 이후에도 이전 비용 정보가 남아 있거나, 입력 가능 여부와 실제 상태가 어긋나는 문제가 발생할 수 있었다.

따라서 속성 비용 UI는 단순한 정보 표시가 아니라, 실제 입력 가능 여부와 직접 연결되는 요소이기 때문에 비용 계산과 입력 상태 판단은 반드시 동일한 기준 상태를 공유해야 했다.

2. 설계  목표

- 속성 최대 상태 여부를 하나의 기준 함수로 통합할 것

- 비용 계산과 UI 표시를 상태 기반으로 처리할 것

- UI에 표시되는 비용 정보가 곧 입력 가능 여부 판단의 기준이 되도록 할 것

- 이후 확률 미니게임, 자동 실행 기능과도 자연스럽게 연동될 수 있는 구조를 만들 것

3. 흐름도

속성 시스템은 속성 부여 시점이나 결과 시점에 UI를 부분적으로 수정하지 않는다.

항상 Update 루프에서 ‘현재 아이템 상태 → 최대 상태 여부 → 비용 계산 → UI 출력’ 의 순서로 일괄 처리함으로써, 어떤 상태 변화 이후에도 이전 계산 결과가 UI에 남지 않도록 했다.

이 구조를 통해 속성 결과 반영, 재화 변화, 자동 실행 등 어떤 상태 변화가 발생하더라도 UI는 항상 동일한 기준으로 출력된다.

4. 구현

4.1. 최대 속성 상태 통합 관리

속성 최대 여부를 여러 조건문으로 흩뿌리지 않고, 하나의 함수로 통합해 관리하였다.

private bool IsMaxEnhanced()
{
    return currentItem != null &&
           currentItem.additionalStat != null &&
           (currentItem.additionalStat.Length >= MaxPropertyCount ||
            currentItem.isPropertyMax);
}

IsMaxEnhanced 함수는 현재 선택된 아이템(currentItem)을 기준으로 속성 부여가 가능한 상태인지 여부를 판단한다.

함수 내부에서는 먼저 currentItem이 존재하는지와 추가 속성 배열(additionalStat)이 초기화되어 있는지를 확인한다.

이후 현재 추가된 속성의 개수가 최대 허용 횟수(MaxPropertyCount)에 도달했는지, 또는 속성 최대 도달을 의미하는 플래그(isPropertyMax)가 설정되어 있는지를 검사한다.

이 조건 중 하나라도 만족할 경우 더 이상 속성 부여가 불가능한 상태로 판단하고 true를 반환한다.

추가 속성 개수(additionalStat.Length)는 실제로 부여된 속성의 수를 기준으로 한 물리적인 제한을 의미하고, isPropertyMax 플래그는 동일 속성의 중복 강화 등으로 인해 더 이상 속성 부여가 허용되지 않는 논리적 제한 상태를 표현한다.

이 함수는 UI 갱신, 비용 계산, 입력 차단 로직에서 공통으로 사용되며, 속성 최대 상태에 대한 판단 기준을 시스템 전반에서 완전히 통일하는 역할을 한다.

이를 통해 어디에서는 최대 상태로 인식하고, 어디에서는 아닌 상태로 인식하는 문제를 구조적으로 차단할 수 있었다.

4.2. 보유 재료 UI 갱신 구조

보유 중인 속성 크리스탈 수량 역시 아이템 상태를 기준으로 매 프레임 갱신한다.

private void UpdateCrystalUI()
{
    if (IsMaxEnhanced())
    {
        haveItemTxt.text = " ";
        return;
    }

    Item crystalItem = im.GetItem(CrystalItemId);
    haveItemTxt.text = crystalItem != null
        ? crystalItem.count.ToString()
        : "0";
}

UpdateCrystalUI 함수는 현재 선택된 아이템 상태와 보유 중인 크리스탈 수량을 기준으로, 속성 패널의 보유 재료 UI를 갱신하는 역할을 한다.

함수는 먼저 IsMaxEnhanced를 호출하여 이미 최대 속성 상태인지 여부를 확인한다.

최대 상태인 경우에는 더 이상 속성 부여가 불가능하므로, 보유 크리스탈 수량 텍스트를 공백으로 처리하여 UI 상에서 추가 시도가 불가능함을 명확히 표시한다.

최대 상태가 아닌 경우에는 ItemManager를 통해 현재 보유 중인 크리스탈 아이템을 조회하고, 해당 아이템의 count 값을 그대로 텍스트 UI에 출력한다.

이 함수는 재료 차감이나 입력 판단과는 분리되어, 현재 상태를 UI에 어떻게 표시할지만을 책임진다.

4.3. 속성 단계 기반 비용 계산 및 UI 출력

속성 비용은 현재 부여된 속성의 개수를 기준으로 계산된다.

private void UpdateUpgradeCostUI()
{
    if (currentItem == null)
    {
        needItemTxt.text = "/ 0";
        needCoinTxt.text = "0";
        return;
    }

    if (IsMaxEnhanced())
    {
        needItemTxt.text = " ";
        needCoinTxt.text = " ";
        upgradeMaxWarningTxt.SetActive(true);
        return;
    }
    upgradeMaxWarningTxt.SetActive(false);

    int count = currentItem.additionalStat != null ? currentItem.additionalStat.Length : 0;

    if (count == 0)
    {
        needItemTxt.text = "/ 1";
        needCoinTxt.text = "2000";
    }
    else if (count == 1)
    {
        needItemTxt.text = "/ 2";
        needCoinTxt.text = "3000";
    }
}

UpdateUpgradeCostUI 함수는 현재 선택된 아이템의 속성 상태를 기준으로, 다음 속성 부여 시도에 필요한 재료와 재화 정보를 UI에 출력하는 역할을 한다.

함수는 내부에서 세 가지 상태를 순차적으로 구분한다.

첫째, 선택된 아이템이 없는 경우에는 비용 정보를 기본값으로 초기화하여 속성 부여 대상이 없음을 표시한다.

둘째, 선택된 아이템이 존재하지만 IsMaxEnhanced()가 true인 경우에는 더 이상 속성 부여가 불가능한 상태로 판단하고, 비용 텍스트를 비워두는 동시에 최대 속성 경고 UI를 활성화한다.

셋째, 속성 부여가 가능한 상태에서는 현재 아이템에 부여된 추가 속성 개수(additionalStat.Length)를 기준으로 단계별 필요 재료 수량과 재화 비용을 계산하여 UI에 출력한다.

속성 단계가 증가할수록 필요한 재료와 재화가 자연스럽게 증가하도록 구성하였다.

최대 속성 상태에 도달한 경우에는 숫자 대신 공백과 경고 UI를 출력해 더 이상 속성 부여가 불가능한 상태임을 직관적으로 전달하였다.

현재는 속성 단계에 따라 비용을 분기 처리했지만, 이후 속성 타입이나 단계가 늘어날 경우 데이터 기반 구조로 자연스럽게 확장할 수 있도록 설계하였다.

5. 개발 의도

속성 시스템에서는 비용 계산 결과 자체보다 UI가 항상 신뢰 가능한 상태를 보여주는 것이 더 중요하다고 판단했다.

그래서 비용 계산 결과를 저장해두는 방식이 아니라, 매 프레임 현재 아이템 상태를 기준으로 UI를 다시 계산하고 출력하는 구조를 선택했다.

이 구조를 통해 속성 결과 반영, 재화 변화, 자동 실행 등 어떤 상태 변화가 발생하더라도 UI와 로직이 서로 다른 상태를 기준으로 동작하는 상황을 방지할 수 있었다.

속성 비용 UI와 최대 속성 상태 관리는 이후 확률 미니 게임 진입 조건과도 직접 연결되며, 이 비용 · 상태 구조를 기반으로 속성 부여 시도 검증과 미니 게임 진입 흐름을 다룬다.