강화 결과 연출 처리 구조

목차

1. 시스템 요구 사항

룰렛 기반 강화 방식과 확률 판정 구조를 구현한 이후,

다음으로 해결해야 했던 문제는 강화 결과를 어떻게 플레이어에게 전달할 것인가였다.

강화 시스템에서 성공과 실패는 단순히 수치만 변경되는 이벤트가 아니라, 플레이어의 감정 반응과 직접적으로 연결되는 핵심 순간이다.

만약 강화 결과가 텍스트 한 줄로만 표시되거나, UI 반응이 늦거나 혹은 성공과 실패의 차이가 명확하지 않다면 강화 시도의 긴장감과 성취감은 크게 떨어질 수 있다.

따라서 이 단계에서는 강화 결과를 즉각적이고 직관적으로 인식할 수 있는 연출 구조를 설계하는 것이 핵심 요구사항이였다.

2. 설계  목표

- 강화 성공 / 실패를 즉시 구분할 수 있을 것

- 시각적·청각적 피드백이 동시에 제공될 것

- 연출 로직이 강화 판정 로직과 섞이지 않을 것

- 연출 방식이 변경되더라도 수정 범위가 최소화될 것

- 강화 결과 인지와 UI 반응 사이에 지연이 발생하지 않을 것

3. 흐름도

강화 결과 연출은 확률 판정 이후 즉시 실행되며, '결과 표시 → 연출 재생 → 상태 정리'의 흐름으로 구성된다.

이 흐름을 통해 강화 결과가 판정되는 순간과 플레이어가 결과를 인식하는 순간이 최대한 일치하도록 구성했다.

4. 구현

위 그림은 본 강화 시스템에서 강화 성공 및 실패 시 결과 연출이 처리되는 전체 흐름을 나타낸다.

강화 결과는 단순히 수치만 변경되는 이벤트가 아니라, 플레이어의 감정 반응과 직결되는 핵심 순간이기 때문에 '결과 인지 → 시각적 연출 → 청각적 피드백'이 즉각적으로 연결되도록 설계하였다.

강화 결과가 판정되는 즉시 성공과 실패를 명확히 구분할 수 있는 텍스트, 색상, 이펙트, 사운드를 함께 출력함으로써, 플레이어가 결과를 직관적으로 인식할 수 있도록 구성하였다.

이를 통해 강화 성공 시에는 성취감을, 실패 시에도 결과에 대한 납득 가능성을 제공하는 것을 목표로 했다.

4.1. 강화 결과 처리 진입점

강화 성공 또는 실패 여부에 따라 아이템 데이터 갱신과 결과 연출을 처리하는 진입점이다.

private void ApplyUpgradeResult(bool success)
{
    if (success)
    {
        int currentGrade = selectedItem.grade;
        int nextGrade = currentGrade + 1;

        selectedItem.grade = nextGrade;

        resultTxt.color = Color.yellow;
        resultTxt.text = $"강화 성공: {currentGrade} -> {nextGrade}";

        UpdateSelectedItemUI();
        UpdateRequirementsByType();
        UpdateUpgradeState();

        PlayResultEffect(true);
    }
    else
    {
        resultTxt.color = Color.red;
        resultTxt.text = "강화 실패";

        PlayResultEffect(false);
    }
}

강화 결과 처리는 ApplyUpgradeResult() 함수 하나로 통합하여 관리한다.

이 함수는 확률 판정 단계에서 전달받은 성공 여부를 기준으로, 강화 성공 또는 실패에 따른 후속 처리를 분기하여 수행한다.

강화 성공 시에는 현재 강화 단계를 기준으로 다음 강화 단계를 계산하여 실제 아이템 데이터에 즉시 반영한다.

이후 강화 단계 변경으로 인해 영향을 받는 UI 요소들을 다시 갱신하여, 강화 결과가 화면에 즉시 반영되도록 구성하였다.

강화 실패 시에는 아이템 데이터에는 어떠한 변경도 가하지 않고, 실패 결과를 시각적으로 명확히 전달하는 데에만 집중한다.

이 함수는 강화 결과에 따른 상태 변경과 연출 호출의 기준점 역할만 담당하며, 이펙트나 사운드의 구체적인 재생 방식은 별도의 함수로 위임하였다.

이를 통해 강화 결과 처리 흐름을 하나의 진입점으로 유지하면서도 각 역할을 명확히 분리할 수 있었다.

4.2. 결과 연출 처리

강화 성공/실패에 따른 시각적·청각적 연출을 한 곳에서 처리한다.

private void PlayResultEffect(bool success)
{
    if (success && successEffect != null)
        successEffect.Play();
    else if (!success && failEffect != null)
        failEffect.Play();

    if (audioSource != null)
    {
        AudioClip clip = success ? successClip : failClip;
        if (clip != null)
            audioSource.PlayOneShot(clip);
    }
}

강화 결과 연출은 PlayResultEffect() 함수 하나로 통합하여 처리하였다.

이 함수는 강화 성공 여부만을 입력값으로 받아, 성공 또는 실패에 맞는 파티클 이펙트와 사운드를 재생한다.

이때, ParticleSystem.Play()는 시각적 효과를 즉각적으로 재생할 수 있는 Unity 제공 기능이다.

강화 성공·실패와 같은 순간적인 이벤트에 적합하다고 판단하여 사용하였다.

또한, AudioSource.PlayOneShot()은 다른 사운드 재생에 영향을 주지 않고 단발성 효과음을 재생할 수 있는 방식으로, 강화 결과 사운드가 다른 UI 사운드와 겹치더라도 자연스럽게 출력되도록 하기 위해 해당 방식을 선택하였다.

5. 개발 의도

강화 결과 연출은 강화 시스템 전체에서 가장 감정적인 반응이 발생하는 구간이다.

이 때문에 연출 코드가 강화 판정 로직과 섞일 경우 코드 가독성과 유지보수성이 빠르게 저하될 가능성이 있었다.

따라서 이 단계에서는 강화 결과 판정, 데이터 반영, 연출 실행을 명확히 분리한 구조를 선택했다.

이 구조를 통해 연출 방식이 변경되거나 강화 UI가 확장되더라도 강화 로직의 안정성을 유지할 수 있었고, 강화 결과 전달 방식만 독립적으로 개선할 수 있는 기반을 마련할 수 있었다.