📁 개발 히스토리

유니티 - 캐릭터를 따라다니는 텍스트 박스(1)

일단몸통박치기 2025. 1. 11. 17:57

산나비처럼 초상화 없이 캐릭터 머리 위에 뜨는 미니 텍스트 박스를 구현해보자

 

 

우선 설정한 조건은 아래와 같다.

1. 텍스트 사이즈에 따라 텍스트 상자 길이가 달라짐
2. 너무 길면 2줄로 표기
3. 글자가 순서대로 출력
예시)
    선
    선생
    선생님
    선생님이
4. 만약에 아직 텍스트가 출력중일때 입력 다시 들어오면 전부 출력
5. 이미 출력 완료인 상태면 Enter 눌렀을때 다음 대사 출력
6. 캐릭터의 머리 위에 출력(좌표 지정)

 

텍스트가 순차적으로 출력되는 것부터 구현했는데 늘 하던대로 Update에서 전체 문장 중 출력할 부분 까지만 TMP에 입력하는 방식으로 구현했다.

 

처음엔 IsTextFlow IsTextEnded 같은 bool값 몇개 사용해서 진행해보려고 했는데 텍스트 박스의 상태가

 

1. 켜는 입력 들어옴

2. 텍스트 박스 등장 애니메이션

3. 텍스트 순차적으로 출력 -> 도중에 새로운 입력 들어오면 중지하고 모두 출력

4. 모두 출력됨

5. 닫는 입력 들어옴

6. 텍스트 박스 사라지는 애니메이션

7. 텍스트 박스 SetActive(false)

 

이 순서로 진행되다보니 bool값을 여러개 만들어 작동하기엔 너무 다양했다.

 

그래서 enum으로 아예 현재 어떤 상태인지 저장하고 if 구문마다 상태를 가져와 작동시키기로 했다.

 

    public enum BoxState
    {
        none,
        Openning,
        Closing,
        TextFlow,
        TextEnded,
        Closed
    }

 

 

텍스트를 출력할때는 string의 일부분만 잘라 출력할 수 있는 Substring 함수를 활용했다.

참고한 내용(https://gent.tistory.com/502)

 

    private void Update()
    {
        if (CurrentBoxState == BoxState.TextFlow)
        {
            time += Time.deltaTime;

            if(time > TextSpeed)
            {
                time = 0;

                if(DialogCount >= CurrentDialog.Length)
                {
                    StopText();
                }
                else
                {
                    Text.text = CurrentDialog.Substring(0, DialogCount);
                    TextSound.Play();
                }
                DialogCount++;
            }
        }

        if (Input.GetKeyDown(KeyCode.E))
        {
            switch (CurrentBoxState)
            {
                case BoxState.TextFlow:
                    StopText();
                    break;
                case BoxState.TextEnded:
                    Text.text = "";
                    CurrentBoxState = BoxState.Closing;
                    break;
                case BoxState.Closed:
                    if (CurrentDialogNumber < Data.Dialog.Count)
                    {
                        SetText(Data.Dialog[CurrentDialogNumber]);
                        CurrentDialogNumber++;
                    }
                    else
                    {
                        SetText("저장된 대화목록이 모두 종료되었습니다. 다시 첫번째 대사로 돌아갑니다.");
                        CurrentDialogNumber = 0;
                    }
                    break;
            }
        }
    }

 

 

 

그리고 외부에

SetText, StopText 함수를 두고 Set에서는 값들을 초기화하고 목표 문장을 저장하는 등의 작업을 수행하고

Stop에서는 출력중인 작업을 중지하고 전체 문장을 출력하는 등의 구현을 진행함.

 

 

 

 

 

 

 

다음은 애니메이션과 상자 사이즈 조절에 대한 고찰이 이어집니다.