[Unity] 간단한 NPC 대화 구현하기

네,가능합니다 ㅣ 2024. 10. 10. 11:02

오늘은 유니티에서 가까운 거리에 있는 NPC와의 대화를 구현해보았다.

 

어제는 휴일이었는데 어제 달렸더니 오늘 개인프로젝트가 도전과제까지 모두 완료돼서 주말에 로아를 할수있게됐다

 

시작해보자 

 

우선 TextMeshPro를 사용하고있어서 TextMeshProUGUI 자료형을 사용하는 경우가 있는데, 이부분은 일반 text 사용시 Text로 바꿔서 사용해주시길 바랍니다.

 

첫번째로 할 일은 상호작용 버튼을 만드는 것입니다.

 

Text를 만들어서 "G를 눌러 상호작용" 같은 글을 적은 뒤 표시하고 싶은 위치에 놔두고 SetActive를 False로 바꿔주세요

 

그리고 아래의 스크립트를 작성합니다. 대부분의 설명을 주석에 적어두었습니다.

 

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

public class NPCInteraction : MonoBehaviour
{
    [SerializeField] private float interactionRange = 2.0f; // 상호작용거리
    [SerializeField] private TextMeshProUGUI interactionText;// 안내메세지
    [SerializeField] private GameObject dialoguePanel;//대화창
    [SerializeField] private GameObject dialogueText;//대화내용
    [SerializeField] private Button closeButton;//대화창끄기버튼
    private Transform playerTransform;//플레이어위치
    private bool isPlayerInRange = false;//플레이어가 NPC에게 가까이 있는지 여부

    private void Start()
    {// 플레이어에게 Player 태그를 달아주셔야 NPC가 인식합니다.
        GameObject player = GameObject.FindGameObjectWithTag("Player");
        if (player != null)
        {//플레이어 위치를 받아오고
            playerTransform = player.transform;
        }
		//대화창 끄기 버튼에 CloseDialoguePanel메서드 연결
        closeButton.onClick.AddListener(CloseDialoguePanel);
		//기본으로 꺼주기
        interactionText.gameObject.SetActive(false);
        dialoguePanel.SetActive(false);
        dialogueText.SetActive(false);
    }
	//대화창끄기메서드
    private void CloseDialoguePanel()
    {
        dialoguePanel.SetActive(false);
        dialogueText.SetActive(false);
    }

    private void Update()
    {
        if (playerTransform == null)
        {
            return;
        }
		//플레이어와 Npc의 거리를 계산하고
        float distance = Vector3.Distance(playerTransform.position, transform.position);
		//그 거리가 상호작용가능 거리보다 작으면
        if (distance < interactionRange)
        {
            if (!isPlayerInRange)
            {//상호작용하라는 키 보여줌
                ShowInteractionText();
            }//상호작용가능거리 true
            isPlayerInRange = true;
			//g를 입력시
            if (Input.GetKeyDown(KeyCode.G))
            {//대화창을 켜는 메소드 호출
                StartDialogue();
            }
        }
        else
        {
            if (isPlayerInRange)
            {
                HideInteractionText();
            }
            isPlayerInRange = false;
        }
    }

    private void ShowInteractionText()
    {
        interactionText.gameObject.SetActive(true);
    }

    private void HideInteractionText()
    {
        interactionText.gameObject.SetActive(false);
    }

    private void StartDialogue()
    {
        dialoguePanel.SetActive(true);
        dialogueText.SetActive(true);
    }
}

 

 

이제 Npc들에게 해당 스크립트를 넣어주고 알맞은 오브젝트들을 넣어주면 끝입니다.

저는 dialogueText를 GameObject타입으로 하고 일반 오브젝트를 넣은뒤 그 오브젝트의 자식으로 text를 넣어두었습니다.