Game/Unity

[유니티] 글자 하나씩 출력하기

nowkoes 2023. 4. 30. 17:02

개요

 

메이플스토리 NPC '윌' 과의 대화

 

 게임을 진행하다 보면 NPC와 대화하는 일이 잦다. 이때 NPC가 출력하는 메시지를 보면, 마치 말을 하듯이 글자가 하나씩 출력되는 것을 볼 수 있는데, 이러한 효과를 어떻게 구현했는지 궁금증이 생겼다. 관련 자료들을 알아본 결과, 유니티에서 제공하는 코루틴 메서드를 이용하면 된다는 것을 알았다.


코루틴(Coroutine)

 

출처: https://docs.unity3d.com/560/Documentation/Manual/Coroutines.html

 

 코루틴(coroutine)은 작업을 다수의 프레임에 분산할 수 있게 하는 기능이라고 한다. 즉, 원하는 시간만큼 함수를 멈춘 뒤 시작하게 할 수 있는 기능을 구현한 함수로서, 글자를 깜빡이게(twinkle) 출력하는 등의 기능을 구현할 때 유용하게 사용된다. 이때 시간 지연을 도입하려면 WaitForSeconds를 사용하면 된다.

 

예를 들어, 3초 뒤 텍스트의 색을 red로 바꾸고 싶다면 다음과 같이 작성하면 된다.

 

Text texts;

...

IEnumerator exampleCoroutine()
{
    float delay = 3f;
    
    yield return new WaitForSeconds(delay); // 3초간 지연
    texts.color = Color.red;
}

 

 이렇게 작성한 코루틴 함수는 StartCorutine() 메서드를 통해 해당 함수를 호출해야 한다. 예를 들어 Start() 메서드에서 해당 함수를 호출하려면 다음과 같이 작성하면 된다.

 

void Start()
{
    StartCoroutine(exampleCoroutine());
}

구현

 

 먼저 배경을 검은색으로 바꾸기 위해 Main Camera의 Clear Flags와 Background의 설정을 다음과 같이 바꿔준다. Clear Flags 컴포넌트카메라의 배경색을 정의하고, 카메라가 보이지 않는 부분을 지울 때 사용되는 것이다. 이를 Solid Color로 바꾸면 카메라의 배경에 단색을 적용할 수 있다. 

 

 

 이후 하이라키 창에 Text - Text Mesh Pro를 추가한 후, Anchor 설정을 건드려 화면 하단에 위치하도록 설정하자.

 

 

 Text(TMP)의 텍스트를 원하는 문장으로 입력하자. 필자의 경우 "Hello everyone! This is a conversation." 으로 설정하였다. 이때 Text에 Wrapping 컴포넌트를 Disable로 바꾼다면, 박스의 크기를 넘는 텍스트도 한 줄로 처리해 준다.

 

 

 이제 해당 텍스트를 타이핑하듯이 출력하는 twinkle이라는 스크립트를 만들어보자.

 

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class twinkle : MonoBehaviour
{
    private string text;
    public TMP_Text targetText;
    private float delay = 0.125f;

 먼저 TMP로 지정된 텍스트 targetText, targetText의 텍스트 정보를 저장할 문자열 text, 문자열 출력 지연 변수 delay를 초기화한다.

 

    void Start()
    {
        text = targetText.text.ToString();
        targetText.text = " ";

        StartCoroutine(textPrint(delay));
    }

 우리의 목표는 빈 화면에서 문자가 출력되게 하는 것이다. 따라서 게임이 실행되면 text에 targetText의 text 정보를 모두 받게 하고, targetText의 text를 공백으로 바꿔놓는다. 

 그리고 StartCoroutnie() 메서드를 통해 textPrint() 함수를 코루틴으로 실행되게 호출한다.

 

    IEnumerator textPrint(float d)
    {
        int count = 0;

        while (count != text.Length)
        {
            if (count < text.Length)
            {
                targetText.text += text[count].ToString();
                count++;
            }

            yield return new WaitForSeconds(delay);
        }
    }
}

 targetText의 text에 미리 저장해 놓은 text[count] 를 하나씩 추가하고, WaitForSecond() 메서드로 일정 시간 기다리게 구현하였다.

 

 

 마지막으로 Canvas에 해당 스크립트를 추가한 후, TMP를 Target Text 부분에 추가하면 완료된다.

 

실행 결과

 

코드 총합본

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class twinkle : MonoBehaviour
{
    private string text;
    public TMP_Text targetText;
    private float delay = 0.125f;

    void Start()
    {
        text = targetText.text.ToString();
        targetText.text = " ";

        StartCoroutine(textPrint(delay));
    }

    IEnumerator textPrint(float d)
    {
        int count = 0;

        while (count != text.Length)
        {
            if (count < text.Length)
            {
                targetText.text += text[count].ToString();
                count++;
            }

            yield return new WaitForSeconds(delay);
        }
    }
}

요약

코루틴(Coroutine)
1. 정의: 시간을 지연하게 해주는 함수로서, 단일 루틴 내에서 여러 번의 진입과 반환을 가능하게 해주는 함수
2. 선언
 - IEnumerator 함수이름(인자)
3. 특징
 a. yield return 구문을 사용하여 실행을 일시 중단하고, 다시 재개할 수 있음
 a. WaitForSeconds 등을 통해 시간을 지연시킨 후 호출할 수 있게 해줌
 b. StartCoroutine()을 통해 코루틴 함수를 호출시켜야 함

 

 

반응형