소소한 나의 하루들

탑다운 2d RPG(3) - 대화창 UI 구축하기 본문

개발/유니티

탑다운 2d RPG(3) - 대화창 UI 구축하기

소소한 나의 하루 2024. 1. 30. 21:15

출처: https://youtube.com/playlist?list=PLO-mt5Iu5TeYI4dbYwWP8JqZMC9iuUIW2&feature=shared

 

📚 유니티 기초 강좌

유니티 게임 개발을 배우고 싶은 분들을 위한 기초 강좌

www.youtube.com

대화창 박스와 아래 화살표를 Sprite로 준비한다.


#1. 대화창 UI

2d 도트 이미지를 사용할 것이기 때문에 Canvas UI오브젝트에서 Pixel Perfect를 체크한다.

그리고 Image UI에 사용할 말풍선 박스 sprite를 적용한다.

UI 이미지의 크기를 조정해도 이미지가 깨지지 않도록 하려면, Image Type을 Sliced로 바꾼다.

*그런데, Slice 옵션을 사용하려면 Sprite Editor설정이 필요하다.

Sprite 모서리를 잡기 위해 Border 값 입력한다. 변화를 시키지 말아야할 ‘모서리’ 부분만큼을 설정해준다. (L / R / T 4px B 5px) 이제 크기를 변화시켜도, 설정한 모서리 부분은 그대로 유지된다.

(보통 대화창은 아래 부분에 그림자가 있기 때문에, Bottom은 5px로 설정)

Border를 설정하고 Apply를 했으면 이제 Image Type을 Sliced로 바꾸고, 대화창 UI를 원하는 크기로 설정한다. (Width: 1800 Height: 300)

 

그리고 대화창이 아래쪽에 붙어있도록 할 것이기 때문에 Anchor를 사용하여 항상 아래쪽에 붙어있게 설정한다.

Shift+Alt를 누르면 오른쪽처럼 보여진다.

Shift를 사용하여 중심점까지 내리면, 여백 계산이 쉬워진다.

Anchor창의 stretch를 보면, 푸른 화살표로 화면에 맞게 늘리도록 설정할 수 있다.

이렇게 다 채우게되면 Rect Transform의 옵션이 Left Right로 바뀌게 된다. 이때 Left와 Right는 여백이 된다. (양 옆 여백을 얼마나 줄 것인지)


#2. 텍스트

그 다음 대화창을 채워줄 텍스트를 입력한다. 대화창 Image UI 안에 Text UI를 생성한다.

Canvas UI 안쪽이 아니라, Image UI 안에 Text UI를 생성해준다.

https://poppyworks.itch.io/silver

 

Silver, a font for games by Poppy Works

A free* pixel font for Latin, Chinese, Korean, Japanese, Cherokee, Runic, Cyrillic, and other character sets.

poppyworks.itch.io

유니티 한글 폰트 import하는 방법
유니티는 기본적으로 한국어로 된 폰트를 지원하지 않는다. 영어만 가능하게 디폴트 세팅되어있기 때문에 몇가지 설정이 필요하다.
1) 폰트 파일(.OTF 또는 .TTF) 다운로드 후 Assets>TextMesh Pro>Fonts에 import한다.
2) 폰트 파일 클릭 후, 우클릭>Create>TextMeshPro>Font Asset 클릭, 생성되는 파란색 폰트파일(.SDF)을 Assets>TextMesh Pro>Resources>Fonts and Materials에 옮긴다.
3) TextMeshPro Text UI에서 적용하면 된다.

 

그리고 사용하고싶은 폰트를 밖에서 불러와서(Import) 텍스트에 적용도 해보고, Anchor로 위치도 조정해준다. (길이: Alt+클릭 / 기준점: Alt+Shift+클릭) 먼저 Shift눌러서 기준점 맞추고, Alt 눌러서 길이 맞춰주면 된다.

*보통 대화는 한가운데서 시작하지 않고, 왼쪽 상단부터 쭉 시작한다.

텍스트 2줄 넣어보면서 높이와 폰트 크기도 적절히 설정한다.

정렬도 할 수 있다.


#3. 데이터 전달

그동안 Debug.Log로만 띄웠던 메세지를 대화창에 띄워보도록 한다.

이러한 것들은 보통 Game Manager를 한번 거친 후에 작동하는 것이 좋다.

데이터 전달을 위한 Game Manager 오브젝트를 생성한다. (이름이 Game Manager일 필요x)

 

Game Manager 오브젝트를 생성하고, GameManager 스크립트를 생성해서, 오브젝트에 스크립트를 적용시킨다.

어떤 정보를 가지고 와야할까

1. 플레이어가 스캔했던 오브젝트 정보

2. 대화창에 텍스트로 나타내야 하기 때문에 TextMesh Pro UI를 스크립트로 가져와야한다.

우선 Text UI의 상위 Image UI도 있으므로 UnityEngine.UI를 using해준다. (UI 프로그래밍 전 꼭 UnityEngine.UI를 넣어준다)

조사할 때, 그 조사하는 대상의 이름만 대화창에 띄워보도록 한다.

 

그리고 플레이어에서 매니저 함수를 호출할 수 있게  gamaManager변수를 생성한다.

저장하고, Player의 Inspector 창에서 public 변수에 GameManager 스크립트를 갖고있는 Game Manager 오브젝트를 드래그해서 잊지말고 채운다.

GameManager 스크립트에 Text UI도 적용시키는 것 잊지말아야 한다.


#4. 상태 전환

지금 대화창이 항상 위에 올라와있다.

따라서 Action() 함수가 호출됐을 때만 SetActive 함수로 대화창 UI를 숨기기&보여주기를 구현한다.

지금 현재 대화창을 띄웠는지, 안띄웠는지 확인을 위해 상태 저장용 변수를 추가한다. (isAction)

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

public class GameManager : MonoBehaviour
{
    public GameObject talkSpace;
    public TextMeshProUGUI talkText;
    public GameObject scanObject;
    public bool isAction;

    public void Action(GameObject scanObj)
    {
        if (isAction) //Exit Action
        {
            isAction = false;
        }
        else //Enter Action
        {
            isAction = true;
            scanObject = scanObj;
            talkText.text = "이것의 이름은 " + scanObj.name + "이라고 한다.";
        }
        talkSpace.SetActive(isAction);
    }

}

SetActive 함수가 isAction을 따라가니까 이렇게 깔끔하게 정리해줄 수 있다.

    void Update()
    {
        //Move Value
        h = gameManager.isAction ? 0 : Input.GetAxisRaw("Horizontal");
        v = gameManager.isAction ? 0 : Input.GetAxisRaw("Vertical");

        //Check Button Down & Up
        hDown = gameManager.isAction ? false : Input.GetButtonDown("Horizontal");
        vDown = gameManager.isAction ? false : Input.GetButtonDown("Vertical");
        hUp = gameManager.isAction ? false : Input.GetButtonUp("Horizontal");
        vUp = gameManager.isAction ? false : Input.GetButtonUp("Vertical");

그런데 플레이어가 대화할 때 움직여서 이탈할 우려가 있다. 그래서 대화할 때는, 플레이어가 이동하지 못하도록 한다.

따라서 상태 변수를 사용해서 플레이어의 이동을 제한한다. isAction이 true일 때 이동x

이제 Jump 키(스페이스바)를 눌러서 Action을 취하게되면, flag가 바뀌기 때문에 다시 움직일 수 있게 된다.


#5. 애니메이션

다시 Canvas UI 안의 Image UI 안에 Image UI를 생성한다.

원래 처음 이미지를 추가하면, 크기가 100*100이다. Inspector에서 Set Native Size를 클릭하면, 원본 크기대로 이미지 사이즈를 맞춘다.

적당한 위치에 배치한다.

UI도 애니메이션 적용가능하다.

 

Animator 컴포넌트를 추가한다.

(1) 일단 Animator를 사용하려면, Animation Controller가 필요하다. (End Cursor)

프로젝트 창의 Animation 폴더에서 Animatoin Controller를 만든 다음, 아까 만들었던 Image UI의 Controller에 적용한다.

(2) Animation 폴더에서 Animation도 생성한다. (Cursor Move)

그리고, 애니메이션 UI를 적용하려는 UI 오브젝트의 Animator 창에서 State를 만들어준다.

위에서 만들었던 Cursor Move 애니메이션을 Motion에 추가해준다. 그리고 Animation 창을 연다.

 

애니메이션이 적용된 오브젝트를 선택하면, 애니메이션 편집 가능하다.

그동안 여러 프레임을 다중선택하여 애니메이션을 생성했는데, 이번에는 직접 애니메이션을 생성한다.

Animation 창에서 Add Property를 눌러 원하는 타입의 프레임을 추가한다. 위치를 조작할 때, Anchor가 적용된 UI는 Anchored Position 선택한다. (x축 y축 z축(2d일 때는 x)을 조작한다.)

반복성 애니메이션은 파일을 클릭해서 Loop Time을 체크해야한다.

Comments