본문 바로가기
유니티3D

유니티3D - NPC와 대화창

지난 게시글에서는 군중 NPC들을 띄우는 부분과
그 중에서 하나의 NPC를 프리팹으로 구워서 사용하는 방법을 알아보았습니다.

https://itadventure.tistory.com/424

 

유니티3D - NPC 랜덤 메이커 UMA! ( 유니티 다목적 아바타 ) #2

지난 게시글에서는 UMA 를 이용한 NPC 생성에 대해서 살펴보았습니다. https://itadventure.tistory.com/423 유니티3D - NPC 메이커? UMA! ( 유니티 다목적 아바타 ) #1 지난 시간까지는 NPC와의 대화창을 만들었..

itadventure.tistory.com

이번 시간에는 드디어 NPC를 만나면 대화창을 띄우는 부분을 살펴보도록 할텐데요.
그간 좀 욕심내서 NPC 대화창에 이미지 대신 NPC 얼굴을 정면을 비추는 카메라를 띄우면 어떨까 해서 자료를 찾아 봤는데 가능하더군요. 그 통쾌함이란!

차후에 이 부분까지 다뤄보도록 하겠습니다 :)


아주 지난 게시글에 대화창은 사실 이 NPC 와의 대화창 구현을 위한 것입니다.
보통 마술사들이 아무것도 없는 허공에서 비둘기를 '짠'하고 나타내어 보여주는 것은,
사실은 없던 비둘기가 갑자기 나타난게 아니라 숨겨두었던 비둘기를 보여주는 것입니다.

이와 같이 유니티에서도 없는 대화창이 갑자기 나타나는게 아니라 다 만들어 놓고 숨겨두었다가
필요한 순간에 짠 나타내는 것이지요.


이 역시 스크립트로 제어가 가능한데요.
스크립트로 대화창을 제어하려면 각 요소에 대해 명확한 이름을 미리 정해두는 것이 좋습니다.
Project 창의 Canvas 폴더 아래에 있는 Panel 과 Text 를

각각 다음과 같이 이름을 변경해 주세요. ( 이름 변경은 오브젝트 선택 후 F2 키를 눌러주시면 됩니다. )
Panel => NPCDialog
Text => NPCText

이 대화창은 여러 NPC 로부터 사용될 것입니다.
정확히는 NPC 주변에 트리거 오브젝트를 설치하고 그 트리거를 사용할텐데요.

트리거로부터 직접 대화창을 제어하는 방식은 한가지 문제가 있습니다.
유니티는 기본적으로 처음에 UI를 감추기 위해서는 Inspector 창에서 선택상자 체크를 해제해야 하는데요.
문제는 이 체크상자를 해제할 경우 트리거가 이 대화상자에 접근할 방법이 없다는 것입니다.

기본적으로 아래 명령어로는 체크 해제된 NPCDialog 오브젝트를 찾을 수 없습니다.
체크가 된 상태에서만 사용 가능하지요,

GameObject.Find("NPCDialog");

전혀 찾을 수 없다고는 볼 수 없지만 우선적으로 찾는 방법이 매우 복잡하고, 효율적이지 않습니다.
덩치 큰 스크립트가 트리거마다 각각 삽입되어야 할테니까요.

참고로 아래 게시글에 관련 팁이 있기는 하나 시도해보지는 않았습니다.

https://forum.unity.com/threads/is-there-no-way-to-get-reference-of-inactive-gameobject.472851/

그보다 쉽고 효율적인 방법은 NPC 대화창을 제어하는 부분을 한 곳에서 관리하는 것입니다.
중앙관리센터라고도 볼 수 있는데요, 크레이는 MainScript 로 지칭하도록 하겠습니다.

이 중앙관리 센터 역시 유니티 특성상 Scene 에 하나의 오브젝트가 배치되고
오브젝트 내부에 스크립트를 삽입해 주어야 작동이 가능한데요.

모양도 필요없고 최소한의 기능만 갖춘 오브젝트면 됩니다.
Empty Object 가 바로 그것이지요.

GameObject - Create Empty 를 선택합니다.

그리고 이름을 Main 으로 입력해주세요. ( F2키! 아시죠? )

그리고 Assets - Scripts 폴더에서 새로운 스크립트를 생성해줍니다.
이름을 MainScript라고 지어주시면 됩니다.

더블클릭해서 C#을 열어주신 다음에, 아래 스크립트를 넣어주세요,
스크립트 설명은 설명편에서 따로 드리도록 하겠습니다.

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

public class MainScript : MonoBehaviour
{
    private GameObject NPCDialog;
    private Text NPCText;

    void Start()
    {
        NPCDialog = GameObject.Find("NPCDialog");
        NPCText = GameObject.Find("NPCText").GetComponent<Text>();
        NPCDialog.SetActive(false);
    }

    public void NPCChatEnter(string text)
    {
        NPCText.text = text;
        NPCDialog.SetActive(true);
    }

    public void NPCChatExit()
    {
        NPCText.text = "";
        NPCDialog.SetActive(false);
    }    
}

다시 유니티로 돌아와서 MainScript 를 Main 오브젝트에 넣어 줍니다.
어떻게 넣어주냐구요?

이렇게요 :)
1) Hierarchy (하이라치) 창에서 Main 오브젝트 선택
2) MainScript 를 클릭, 마우스 버튼을 놓지 말고
3) Inspector(인스펙터) 창에 드래그해서 넣기

"ㅇㅇㅇ 오브젝트에 ㅇㅇㅇ 스크립트를 넣어주세요"로 이 동작을 알아들으실 수 있으면
크레이가 편할것 같아 추후에는 이렇게 진행하려 합니다.

물론 앞으로 몇번은 더 설명드리긴 할거지만요 :)

이제 다음으로 NPC 주변에 트리거를 심도록 할텐데요,
지난 게시글을 참조해서 2개의 NPC를 프리팹으로 구워 바닥에 세팅하신 상황에서 시작하도록 하겠습니다.

NPC 를 구워 바닥에 세팅하는 방법은 지난 게시글과 그 이전 게시글을 참조해 주세요.

https://itadventure.tistory.com/423

 

유니티3D - NPC 메이커? UMA! ( 유니티 다목적 아바타 ) #1

지난 시간까지는 NPC와의 대화창을 만들었다면, https://itadventure.tistory.com/422 유니티3D - NPC 대화창 #4. 이미지 UI, 그리고 마스크 이미지 지난 게시글에서는 리치 텍스트란걸 사용하여 대화창의 대사

itadventure.tistory.com

https://itadventure.tistory.com/424

 

유니티3D - NPC 랜덤 메이커 UMA! ( 유니티 다목적 아바타 ) #2

지난 게시글에서는 UMA 를 이용한 NPC 생성에 대해서 살펴보았습니다. https://itadventure.tistory.com/423 유니티3D - NPC 메이커? UMA! ( 유니티 다목적 아바타 ) #1 지난 시간까지는 NPC와의 대화창을 만들었..

itadventure.tistory.com

Scene 에는 2명의 NPC 가 배치되어 있는 상황입니다.

각각의 NPC 에게 가면 대화창과 다른 대사가 뜨게 하려고 하는데요.
NPC 에게는 콜라이더는 있지만 트리거는 없으므로 트리거를 하나씩 만들어보도록 하지요.

먼저 Hierarchy 창에서 첫번째 NPC를 더블 클릭합니다
더블클릭하는 이유는 더블클릭한 위치가 자동으로 중심이 되기 때문에 다음에 생성될 오브젝트를 딱 이 위치에 놓기 편하기 때문입니다.

이어서 큐브를 하나 만들어 줍니다.
GameObject - 3D Object - Cube 메늎입니다.

그러면 이와 같이 NPC를 포위(?)하는 하나의 큐브가 생겨날텐데요.

우리는 이 큐브를 트리거 용도로 사용할거니 우측 Inspector 창에서 다음 속성들을 변경해 줍니다.
Transform(트랜스폼) 컴포넌트의 Scale : X 1.5, Z 1.5 - 크기를 변경해 줍니다.

Mesh Renderer (메시 렌더러) 컴포넌트 체크 상자 해제. - 큐브의 모양을 보이지 않게 합니다.

Box Collider(박스 콜라이더) 컴포넌트Is Trigger(이즈 트리거) 체크 상자 체크 - 이 것으로 이 물체는 관통할 수 있으며 충돌을 검사할 수 있는 물체가 됩니다.

만들어진 큐브를 해당 NPC 하위로 드래그해 옯긴 다음에 NPC 이름과 비슷하게 지어보도록 하지요.
NPC_W01 이라면 Trigger_W01 로 지어보도록 합시다. 

동일한 방법으로 다른 NPC도 동일한 트리거를 만들어 주세요.

이제 이 트리거에 넣을 스크립트를 하나 만듭니다.

Assets - Scripts 폴더에 NPC_Trigger 라는 스크립트를 생성한 다음에,

해당 스크립트를 더블 클릭, 비주얼 스튜디오에서 아래 스크립트를 입력해 주세요.

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

public class NPC_Trigger : MonoBehaviour
{
    public string ChatText = "";
    private GameObject Main;
    void Start()
    {
        Main = GameObject.Find("Main");
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "myplayer")
        {
            Main.GetComponent<MainScript>().NPCChatEnter(ChatText);
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.tag == "myplayer")
        {
            Main.GetComponent<MainScript>().NPCChatExit();
        }
    }
}

다시 유니티로 돌아와 이 스크립트를 금방 생성했던 트리거 오브젝트 2개에 각각 넣어 주세요.
3박자입니다 :)
1) 트리거 오브젝트 선택
2) NPC_Trigger 스크립트를 클릭, 마우스 버튼을 놓지 말고
3) Inspector 창의 빈 곳에 드래그

이 스크립트를 넣으면 ChatText 라는 텍스트 속성이 활성화될텐데요.
처음에는 공란으로 비어 있을 겁니다.

NPC 한쪽의 트리거에는 아래 내용을, ( 또는 여러분이 원하시는 내용을 )

<color=#ff7777>[NPC]</color>자모 월드에는 <size=20><color=#ffff33>즐거움</color></size> 이 있어요!

또 다른 NPC 한쪽의 트리거에는 아래 내용을 넣어 주세요,

<color=#ff7777>[NPC]</color>가상 세계에 오신 것을 <size=30>환영</size>하오!

자. 이제 플레이를 시작합니다.
그러면 평소와는 달리 대화창이 화면에 나오지 않는 것을 보실 수 있는데요.
MainScript 에서 시작하자 마자 이를 숨기기 때문입니다.

하지만 우리의 자모 로봇 주인공을 저쪽 NPC로 옮겨보시면,
아래와 같은 대화창이 뜨는 것을 보실수 있는데요.

다시 NPC 에게서 떨어지면, 대화창이 사라지는 것을 보실 수 있습니다.

그리고 또 다른 NPC를 방문해보면, 다른 스타일의 대화창이 뜨는 것을 보실수 있지요.

스크립트 설명은 다음 게시글에 진행하도록 하겠습니다.
오늘은 여기까지.
필요하신 분들께 도움이 되셨을까 모르겠군요.
실습해보시는 분들께는 건투를 빕니다 :)

오늘도 여기까지 읽어주셔서 감사합니다.


다음게시글. NPC와 대화창(설명편)

https://itadventure.tistory.com/426

 

유니티3D - NPC와 대화창 (설명편)

이번 게시글에서는 지난번에 작동해보았던 NPC와 대화창 스크립트에 대한 설명을 드리도록 하겠습니다. https://itadventure.tistory.com/425 유니티3D - NPC와 대화창 지난 게시글에서는 군중 NPC들을 띄우

itadventure.tistory.com