■ 구현 기능
+ 클릭시 카메라가 확대 되는 기능 추가
· NPC 클릭 시 대화창(UI) 표시
· 선택지 버튼 클릭에 따라 다음 대화 흐름이 변화
■ 구현 과정
씬 구현 과정은 9주차와 동일
1.[DialogueNode] ScriptableObject 생성
· 대사와 선택지를 하나의 ScriptableObject(DialogueNode)로 관리
· 선택지는 텍스트와 연결될 다음 노드를 리스트로 저장
[DialogueNode.cs]
[CreateAssetMenu(fileName = “New Dialogue Node”, menuName = “Dialogue/Node”)]
public class DialogueNode : ScriptableObject
{
public string text;
public List options;
[System.Serializable]
public class Option
{
public string optionText;
public DialogueNode nextNode;
}
}
* 별도의 DialogueOption.cs 스크립트를 만들지 않고, DialogueNode 안에 Option 클랙스를 내부 클래스로 선언하여 간결한 구조로 구현
2. DialogueManager2.cs – 대화창 제어 스크립트
· 대화 UI 패널을 관리하고, 선택지를 동적으로 표시
· 선택지를 클릭하면 연결된 다음 노드를 실행하거나 종료
· 싱글턴 패턴으로 전역 접근 가능하게 구성
[DialogueManager2.cs ]
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class DialogueManager2 : MonoBehaviour
{
public static DialogueManager2 instance;
public TMP_Text dialogueText;
public List<Button> optionButtons;
[Header(“대사 데이터”)]
private DialogueNode currentNode;
private void Awake()
{
if(instance == null)
instance = this;
else
Destory(gameObject);
dialoguePanel.SetActive(false);
public void ShowNode(DialogueNode node)
{
currentNode = node;
dialoguePanel.SetActive(true);
dialogueText.text = node.text;
for (int i = 0; i < optionButtons.Count; i++)
{
if (i < node.options.Count)
{
optionButtons[i].gameObject.SetActive(true);
optionButtons[i].GetComponentlnChildren<TMP_Text>().text = node.options[i].optionText;
int index = i; // 클로저 오류 방지
optionButtons[i].onClick.RemoveAllListeners();
optionButtons[i].onClick.AddListener(() => OnOptionSelected(node.options[index]));
}
else
{
optionButtons[i].gameObject.SetActive(false);
}
}
}
3. NPCClick.cs – NPC 클릭 시 대화 호출 스크립트 ( 9주차 동일 )
· NPC 오브젝트에 붙여서 마우스 클릭 시 DialogueManager2를 호출
[NPCClick.cs]
public class NPCClick2 : MonoBehaviour
{
public DialogueNode startingNode;
private void OnMouseDown()
{
if (DialogueManager2.instance != null)
{
if (DialogueManager2.instance.lsDialogueVisible())
DialogueManager2.instance.HideDialogue();
else
DialogueManager2.instance.ShowNode(startingNode);
}
}
}
4. 연결하기 (inspector)
4.1 DialogueManager 오브젝트에 DialogueManager.cs 스크립트 추가
4.2 아래 항목을 드래그 해서 연결
· Dialogue Panel -> DialoguePanel
· Dialogue Text -> DialogueText
· Option Buttons -> Option1, Option2 버튼 배열로 추가
4.3 NPC에 NPCClick.cs 추가
· firstNode에 처음 나올 DialogueNode를 드래그해서 연결
4.4 Assets에서 우클릭 -> Create > Dialogue > Node로 대화 노드 생성
· npcText에 텍스트 입력
· options 배열로 선택지 입력
· 각 선택지의 nextNode에 다음 노드 연결
5. 4.4 Assets에서 우클릭 -> Create > Dialogue > Node로 대화 노드 생성 과정 (Node1)
· Assets에서 우클릭 -> Create > Dialogue > Node로 대화 노드 생성
· DialogueNode 인스펙터 창에서 설정 (Node1의 Inspector창)
Text – NPC가 말할 대사를 입력하는 칸
· Options – 선택지 리스트, 몇 개를 만들지 설정하고 각각 내용을 입력
5.2. NPC 대사 입력하기 (Text)
· Text 칸에 NPC가 플레이어에게 말할 문장 입력
5.3. 선택지(Options) 설정
· Options 필드 오른쪽에 있는 작은 삼각형을 눌러 배열 크기 지정
예) 2로 설정하면 선택지 2개 생성
· 각 선택지 항목에 아래 내용 채우기
OptionText – 플레이어가 선택할 선택지 문구
NextNode – 이 선택지를 고르면 이어질 다음 DialogueNode 에셋 참조
5.4. 다음 노드 연결
· NextNode 필드에 마우스를 클릭하면, Assets 폴더 내에 생성된 다른 DialogueNode 에셋 리스트가 나옴
· 연결하려는 다음 노드를 드래그하거나 선택해서 넣기
5.5. 예시 흐름 만들기
· Node1
– Text : “Good afternoon May I help you?”
– Options :
· Option 0
· OptionText : “Hi!”
· NextNode : Node2 (다음 노드)
· Option 1
· OptionText : “good bye”
· NextNode : null (대화 종료)
· Node2
– Text : “Have a nice day!”
– Options : 빈 배열 또는 종료
5.6 [DialogueNode.cs] : Dialogue > Node 생성을 위해 사용
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = “NewNode”, menuName = “Dialogue/Node”)]
public class DialogueNode : ScriptableObject
{
[TextArea(3, 10)]
public string text;
public List<DialogueOption> options = new List<DialogueOption>();
}
[System.Serializable]
public class DialogueOption
{
public string optionText;
public DialogueNode nextNode;
}
7. NPC 오브젝트에 연결된 첫 노드 지정
· NPC GameObject에 붙인 NPCClick.cs 컴포넌트의 firstNode 필드에 대화 시작할 노드(Node1)를 드래그 앤 드롭으로 넣어주기
8. 외 사용한 scripts
– [Dialogue.cs] : startingNode를 사용하기 위한 스크립트
using UnityEngine;
[CreateAssetMenu(fileName = “NewDialogue”, menuName = “Dialogue”)]
public class Dialogue : ScriptableObject
{
public string dialogueName;
public DialogueNode[] nodes;
}
+ 클릭시 카메라가 확대 되는 기능 추가
8.1. [NPCClick2.cs] 코드 수정
using UnityEngine;
public class NPCClick2 : MonoBehaviour
{
public DialogueNode startingNode;
public Camera mainCamera; // 카메라 연결
public float zoomedInSize = 3f; // 줌인 시 크기
private float originalSize; // 원래 크기 저장
private void Start()
{
if (mainCamera == null)
{
mainCamera = Camera.main;
}
originalSize = mainCamera.orthographicSize;
}
private void OnMouseDown()
{
if (DialogueManager2.instance != null)
{
if (DialogueManager2.instance.lsDialogueVisible())
{
DialogueManager2.instance.HideDialogue();
mainCamera.orthographicSize = originalSize; // 카메라 원래대로
}
else
{
DialogueManager2.instance.ShowNode(startingNode);
mainCamera.orthographicSize = zoomedlnSize; // 카메라 확대
}
}
}
}
8.2. NPC Inspector > NPC Click2 (Script) > Main Camera > Hierarchy에서 Main Camera 드래그
■ 에러 발견 및 해결
1. 실행이 되지 않음 – C# 스크립트에 문법 오류(컴파일 에러)
· 에러 메시지 : All compiler errors have to be fixed before you can enter palymode!
· 원인 : DialogueOption.cs 없이 내부 클래스를 쓸 때 발생한 문법 오류
– DialogueNode.cs 에서 선택지를 따로 DialogueOption 클래스로 분리하지 않고 Option 이라는 내부 클래스로 정의 했는데,
– DialogueManager2.cs에서 DialogueOption을 참조하는 코드가 여전히 남아 있어서 정의되지 않은 클래스 오류 발생
· 해결 방법 : DialogueOption.cs를 쓰지 않기로 하고, DialogueNode.Option 으로 코드 수정
2. ScriptableObject 생성 메뉴 노출 오류 해결
Assets > create > dialoge > Node 메뉴가 나타나지 않는 문제 발생
· 해결 방법 : DialogueNode.cs 파일 상단에 다음 어트리뷰트를 추가
[CreateAssetMenu(fileName = “New Dialogue Node”, menuName = “Dialogue/Node”)]
■ 실행 영상