내일배움캠프/Unity
Unity 2D Top Down (NPC 대화 출력)
danpat77
2025. 2. 19. 21:00
게임에서 빠질 수 없는 NPC와 대화 오늘은 이걸 간단하게 구현을 해보자
NpcTalkDate.cs 제작
우선 각 종족별 NPC들의 대화말을 정리해 줄 리스트들을 만들어주고
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
public class NpcTalkData : MonoBehaviour
{
public List<string> elflist;
public List<string> dwarflist;
public List<string> humanlist;
public List<string> guidelist;
private void Awake()
{
elflist = new List<string> {
"바람은 모든 것을 알고 있지... 네가 여기에 온 이유도 말해줄 수 있을까?",
"숲의 귓가에 속삭여 보게. 네 목소리가 나뭇잎을 흔들지 않는다면 거짓이야.",
"시간은 우리에게 친절하지만, 인간에게는 그렇지 않지. 하지만... 넌 예외일까?",
"이 땅의 마법이 흐려지고 있어. 그대가 손을 내밀어 주겠나?",
"신성한 숲을 지나려는가? 네 발걸음이 가벼운지 시험해 보겠어."};
dwarflist = new List<string> {
"우린 바위처럼 단단하지! 하지만 술 한잔 앞에선 무너지는 법이지, 크하하하!",
"내가 만든 도끼라면 바위도 두 동강 내지! 자, 이거 하나 사지 않겠나?",
"엘프 녀석들은 너무 가벼워. 어휴, 그들의 맥주 맛이야말로 최악이지!",
"일할 시간인가? 아니면 한 잔 할 시간인가? 어차피 정답은 후자지!",
"내 조상 대대로 전해 내려오는 전설의 망치가 있다고! 근데 어디 뒀더라..." };
humanlist = new List<string> {
"이곳에서 여행자는 환영받지. 하지만 돈이 없다면 이야기가 좀 다를걸?",
"왕국은 겉으로는 평온해 보이지만, 그 속은 썩어가고 있어.",
"너 같은 모험가가 또 나타날 줄이야. 지난번 녀석은 늑대한테 잡아먹혔지.",
"정의? 명예? 다 좋지만, 빈 주머니엔 아무 소용 없지 않나?",
"조심하게나, 밤이 되면 거리는 더 위험해지니까."};
guidelist = new List<string> {
"오! 새로운 얼굴이네? 처음 왔다면 내가 좀 알려줄게!\n\n[스페이스바를 눌러 다음 대화로 넘어갈 수 있다.]",
"저기 오른쪽에 보이는 포탈 보이지? 스페이스바를 눌러 상호작용하면 미니게임에 들어갈 수 있어! 실력을 시험해보는 거지. 꽤 재미있으니까 한 번 도전해보는 것도 나쁘지 않을 걸? [계속]",
"그리고 바로 옆에 있는 커다란 동상, 눈에 띄지? 스페이스바를 눌러 상호작용하면 랭킹을 확인할 수 있어. 네가 얼마나 잘했는지, 다른 사람들은 얼마나 대단한지 확인할 수 있다고! [계속]",
"자, 뭐부터 해볼래? 그냥 멍하니 서 있지 말고 한 번 움직여보라고! 하하!"};
}
}
NpcInfo.cs
이제 NPC들에게 부여해줄 Type을 제작하여 각 종족에 알맞는 대화말을 NpcTalkData.cs에서 호출
using TMPro;
using UnityEngine;
public enum NpcType //NPC 종족
{
elf,
dwarf,
human,
guide
}
public class NpcInfo : MonoBehaviour
{
[SerializeField] private NpcType type;
NpcTalkData npcTalkData;
UIManager uimanager;
public TextMeshProUGUI NpcName;
public TextMeshProUGUI NpcTalk;
public string Name; // NPC이름은 직접 입력
bool guideTalking = false;
int i = 0;
private void Start()
{
npcTalkData = FindAnyObjectByType<NpcTalkData>();
uimanager = FindAnyObjectByType<UIManager>();
}
public void printText()
{
int selet = Random.Range(0, 5); // 랜덤 값을 이용해 NPC 말을 리스트에서 랜덤으로 호출
switch (type)
{
case NpcType.elf:
NpcTalk.text = npcTalkData.elflist[selet];
break;
case NpcType.dwarf:
NpcTalk.text = npcTalkData.dwarflist[selet];
break;
case NpcType.human:
NpcTalk.text = npcTalkData.humanlist[selet];
break;
case NpcType.guide:
guideTalking = true;
i = 0;
break;
}
}
private void Update()
{
if (guideTalking)
{
NpcTalk.text = npcTalkData.guidelist[i];
if (Input.GetKeyDown(KeyCode.Space) && i < 4)
{
NpcTalk.text = npcTalkData.guidelist[i];
if (i < 3) i += 1;
}
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Player") // 충돌 이벤트를 통해 플레이어와 닿으면 작동
{
printText();
if (npcTalkData == null)
NpcName.text = Name;
uimanager.SetOnNPCTalkUI(); // 대화 UI 켜기
}
}
private void OnCollisionExit2D(Collision2D collision) // 충돌에서 벗어나면 UI종료
{
uimanager.SetOffNPCTalkUI(); // 대화 UI 끄기
if (guideTalking == true) guideTalking = false;
}
}
호출한 대화말은 충돌 이벤트를 통해 대화를 출력해주면 이런 식으로 대화가 표시 된다
uimanager.SetOnNPCTalkUI();부분과 uimanager.SetOffNPCTalkUI();부분은 NPC들의 대화창 UI를 다른 UI들과 같이 관리 하려고 만든 스크립트 안에 있는 것이라서 저 부분을 지우고 NPC들의 대화창 UI를 담을 GameObject 코드를 추가하여 SetActive()를 이용하여 켯다가 끄면 된다.