NPCdata.cs
using UnityEngine;
[CreateAssetMenu(fileName = "NewNPCData", menuName = "Dialogue/NPC Data")]
public class NPCData : ScriptableObject
{
public string npcName;
public string[] dialogueLines;
}
NPC 대화정보를 스크립터블 오브젝트로 관리하고 DialogueManager.cs, NPC.cs에 참조한뒤
매니저를 통해 npc에 데이터를 전달한다.
더보기
using UnityEngine;
using TMPro;
public class DialogueManager : MonoBehaviour
{
public static DialogueManager Instance;
[SerializeField] private TextMeshProUGUI dialogueText;
[SerializeField] private TextMeshProUGUI npcNameText;
[SerializeField] private GameObject dialoguePanel;
private NPCData currentNPCData;
private int dialogueIndex;
private void Awake()
{
if (Instance == null)
Instance = this;
else
Destroy(gameObject);
dialoguePanel.SetActive(false);
}
public void StartDialogue(NPCData npcData)
{
currentNPCData = npcData;
dialogueIndex = 0;
dialoguePanel.SetActive(true);
// NPC 이름 표시
npcNameText.text = currentNPCData.npcName;
// 첫 대화 출력
NextDialogue();
}
public void NextDialogue()
{
// 대화 종료
if (dialogueIndex >= currentNPCData.dialogueLines.Length)
{
EndDialogue();
return;
}
// 대화 출력
dialogueText.text = currentNPCData.dialogueLines[dialogueIndex];
dialogueText.gameObject.SetActive(true);
dialogueIndex++;
}
public void EndDialogue()
{
dialoguePanel.gameObject.SetActive(false);
dialogueText.text = string.Empty;
npcNameText.text = string.Empty;
}
public bool DialogueActive()
{
return dialoguePanel.activeSelf;
}
대화 text, npc 이름, panel을 변수로 선언하고
npc 데이터를 매개변수로 전달해준다.
dialouge 인덱스 번호에 따라 대화를 다르게 출력한다.
DialougeActive 함수를 통해 패널 활성화 여부를 판단하여 켜고 끄고를 반복해준다.
더보기
NPC.cs
using UnityEngine;
public class NPC : MonoBehaviour
{
public NPCData npcData;
private bool isPlayerNearby;
private void Update()
{
if (isPlayerNearby && Input.GetKeyDown(KeyCode.E))
{
if(DialogueManager.Instance.DialogueActive())
{
DialogueManager.Instance.NextDialogue();
}
else
{
DialogueManager.Instance.StartDialogue(npcData);
}
}
}
private void OnTriggerEnter2D(Collider2D other)
{
Player player = other.GetComponent<Player>();
if (player)
{
isPlayerNearby = true;
}
}
private void OnTriggerExit2D(Collider2D other)
{
Player player = other.GetComponent<Player>();
if (player)
{
isPlayerNearby = false;
DialogueManager.Instance.EndDialogue();
}
}
플레이어가 조건(근접(TriggerEnter)또는 벗어날때(TriggerExit))에 따라
매니저를 통해 전달받은 StartDialouge, EndDialouge 함수를 호출해준다.
일단 E키 상호작용 getkeydown으로 했는데 인풋시스템으로 리펙토링 하면 좋을 것 같다.
콜라이더 범위를 설정하여 다가가면 상호작용 할 수 있도록 설정
'개발일지 > 최종프로젝트' 카테고리의 다른 글
241210(화) [NPC 대화 업데이트] (1) | 2024.12.10 |
---|---|
241209(월) [기술면접 메모] (0) | 2024.12.09 |
241205(목) [시네머신(Cinemachine)을 이용한 카메라 범위 제한] (0) | 2024.12.05 |
241204(수) [유한상태머신을 이용한 2D 이동 구현하기] (0) | 2024.12.04 |
241203(화) [유한상태머신 적용하기] (0) | 2024.12.03 |