[패스트캠퍼스 수강 후기] 올인원 패키지 : 유니티 포트폴리오 완성 100% 환급 챌린지 22회차 미션 시작합니다.
02 디아블로 게임 - 39. 40 챕터를 진행합니다.
NPC와의 대화를 위한 Dialog System 구현입니다.
* Dialogue -> DialogManager에게 내용 전달하면 -> DialogUI에 표시
+ Name - 대화 이름
+ Sentences - 대화 내용
[Serializable]
public clas Dialogue_New
{
public string name; // NPC 이름
[TextArea(3, 10)]
public string[] sentences; // 대화문장 배열
}
public class DialogueManager_New : MonoBehaviour
{
private static DialogueManager_New instance; // Singleton Pattern
public static DialogManager_New Instance = >instance;
public Text nameText;
public Text dialogueText;
public Animator animator = null;
private Queue<string> sentences;
public event Action OnStartDialogue; // 다이알로그 시작 이벤트
public event Action OnEndDialogue; // 다이알로그 종료 이벤트
private void Awake() {
instance = this;
}
void Start() {
sentences = new Queue<string>();
}
public void StartDialogue(Dialogue_New dialogue) {
OnStartDialogue?.Invoke();
animator?.SetBool("IsOpen", true);
nameText.text = dialogue.name;
sentences.Clear();
foreach (string sentence in dialogue.sentences) {
sentences.Enqueue(sentence);
}
DisplayNextSentence();
}
public void DisplayNextSentence() {
if (sentences.Count == 0) { EndDialogue(); return; }
string sentence = sentences.Dequeue();
StopAllCoroutines();
StartCoroutine(TypeSentence(sentence));
}
public IEnumerator TypeSentence(string sentence) {
dialogueText.text = string.Empty;
yield return new WaitForSeconds(0.25f); // 애니메이션 완료 대기
foreach (char letter in sentence.ToCharArray()) {
dialogueText.text += letter; // 하나하나 문자로 찍히는 효과
yield return null;
}
}
pubic void EndDialogue() {
animator?.SetBool("IsOpen", false);
OnEndDialogue?.Invoke();
}
}
자료 구조인 Queue와 Stack에 대한 설명도 간단히 해주십니다.
Queue : First Input First Out -> 먼저 넣은 것부터 뽑아서 사용.
Stack : First Input Last Out -> 먼저 넣은 것을 제일 마지막에 사용.
해당 대화 구현을 위한 DialogBox GameObject Unity 구성 화면입니다.
Continue 버튼으로 다음 문장을 진행. DisplayNextSentence()를 호출합니다.
이를 사용하는 DialogueNPC를 구현합니다.
public class DialogueNPC_New : MonoBehaviour, IInteractable
{
[Serializable]
Dialogue dialogue;
bool isStartDialogue = false;
GameObject interactGO;
[SerializeField]
float distance = 2.0f;
public float Distance => distance;
public void Interact(GameObject other) {
float calcDistance = Vector3.Distance(other.transform.position, transform.position);
if (calcDistance > distance) return;
if (isStartDialogue) return;
interactGO = other;
DialogueManager_New.Instance.OnEndDialogue += OnEndDialogue;
isStartDialogue = true;
DialogueManager_New.Instance.StartDialogue(dialogue);
}
public void StopInteract(GameObject other) {
isStartDialogue = false;
}
private void OnEndDialogue() {
StopInteract(interactGO);
}
}
Unity에서의 NPC 구성 화면입니다.
Sentences 3개를 넣어서 동작 테스트를 해보도록 합니다.
대화상대를 우클릭하면 대화 상대에게 이동을 하고 distance 거리내로 다가가게 되면 StartDialogue()를 시작으로 첫번째 문장이 표시됩니다.
[Continue] 버튼을 클릭하면 다음 문장을 보여주고 마지막 문장이 완료되면 EndDialogue()로 사라지는 애니메이션이 구동되어 없어집니다.
이제 Quest System을 구현해 보도록 하겠습니다.
QuestObject는 ScriptableObject를 상속받아 구현합니다.
QuestStatus
+ None: X
+ Accepted: 퀘스트 수락
+ Completed: 퀘스트 완료
+ Rewarded: 퀘스트 보상 완료
public enum QuestType_New {
DestroyEnemy,
AcquireItem,
}
[Serializable]
public class Quest_New
{
public int id;
public QuestType_New type;
public int targetID; // 적의 정보
public int count; // 적의 수
public int completedCount;
pubic int rewardExp;
public int rewardGold;
public int rewardItemId;
public string title;
public string description;
}
pubic enum QuestStatus {
None,
Accepted,
Completed,
Rewarded,
}
[CreateAssetMenu(filename = "New Quest", menuName = "Quest System/Quests/New Quest_New")]
public class QuestObject_New : ScriptableObject
{
public Quest_New data = new Quest_New();
public QuestStatus_New status;
}
[CreateAssetMenu(fileName = "Quest Database", menuName = "Quest System/Quests/New Quest Database")]
public class QuestDatabaseObject_New : ScriptableObject
{
public QuestObject_New[] questObjects;
public void OnValidate() {
for (int index = 0; index < questObjects.Length; index++) {
questObjects[index].data.id = index;
}
}
}
Quest를 2가지 추가하였고, 2가지 퀘스트를 구성하였습니다.
첫번째는 적을 잡아와라, 두번째는 특정 아이템을 구해오라는 퀘스트로 구성하였습니다.
public class QuestManager_New : MonoBehaviour
{
private static QuestManager_New instance;
public static QuestManager_New Instance => instance;
public QuestDatabaseObject_New questDatabase;
public event Action<QuestObject_New> OnCompletedQuest;
private void Awake() {
instance = this;
}
public void ProcessQuest(QuestType_New type, int targetId) {
foreach (QuestObject_New questObject in questDatabase.questObjects) {
if (questObject.status == QuestStatus.Accepted && questObject.data.type == type &&
questObject.data.targetId == targetId) {
questObject.data.completedCount++;
if (questObject.data.completedCount >= questObject.data.count) {
questObject.status = QuestStatus.Completed;
OnCompletedQuest?.Invoke(questObject);
}
}
}
}
}
public class QuestNPC_New : MonoBehaviour, IInteractable
{
public QuestObject questObject;
public Dialogue readyDialogue; // 퀘스트 준비
public Dialogue acceptedDialogue; // 이미 수락된 경우
public Dialogue completedDialogue; // 완료된 퀘스트
bool isStartQuestDialogue = false;
GameObject interactGO = null;
void Start() {
QuestManager_New.Instance.OnCompletedQuest += OnCompletedQuest;
}
// IInteractable 관련 구현은 DialogueNPC_New와 거의 유사하므로 복사하여 수정.
}
그리고 EnemyController_Range에서 TakeDamage()가 발생할 때 적이 죽는 타이밍 즉, IsAlive가 아닌 경우가 발생할 때
QuestManager.Instance.ProcessQuest(QuestType.DestroyEnemy, 0);
를 호출하여 Quest를 확인하도록 처리합니다.
마찬가지로 InventoryObject에서 AddItem()이 발생할 때 관련 퀘스트를 확인하기 위하여
QuestManager.Instance.ProcessQuest(QuestType.AcquireItem, 1);
를 호출하여 Quest를 확인하도록 처리합니다.
Unity에서 QuestNPC를 2개 구성하였습니다.
하나는 적을 죽일 때의 Quest이고, 하나는 아이템을 얻는 Quest입니다.
실행을 하면 적을 죽이는 퀘스트와, 아이템을 얻어야 완료되는 2가지 퀘스트가 잘 구동되는 것을 확인할 수 있습니다.
실제로는 게임을 제작할 때 기획 의도에 맞게 Quest를 구성하면 되겠지요.
<위의 코드들은 제가 보면서 주요한 함수, 코드를 확인하기 위해 타이핑한 용도로, 전체 소스코드가 아님에 주의해 주세요. 전체 코드는 교육 수강을 하면 완벽하게 받으실 수가 있답니다 ^^>
패스트캠퍼스 - 올인원 패키지 : 유니티 포트폴리오 완성 bit.ly/2R561g0
유니티 게임 포트폴리오 완성 올인원 패키지 Online. | 패스트캠퍼스
게임 콘텐츠 프로그래머로 취업하고 싶다면, 포트폴리오 완성은 필수! '디아블로'와 '배틀그라운드' 게임을 따라 만들어 보며, 프로그래머 면접에 나오는 핵심 개념까지 모두 잡아 보세요!
www.fastcampus.co.kr
'[컴퓨터] > 웹 | 앱 | 게임 개발' 카테고리의 다른 글
[패스트캠퍼스 수강 후기] 올인원 패키지 : 유니티 포트폴리오 완성 100% 환급 챌린지 24회차 미션 (0) | 2020.11.11 |
---|---|
[패스트캠퍼스 수강 후기] 올인원 패키지 : 유니티 포트폴리오 완성 100% 환급 챌린지 23회차 미션 (0) | 2020.11.10 |
[패스트캠퍼스 수강 후기] 올인원 패키지 : 유니티 포트폴리오 완성 100% 환급 챌린지 22회차 미션 (0) | 2020.11.09 |
[패스트캠퍼스 수강 후기] 올인원 패키지 : 유니티 포트폴리오 완성 100% 환급 챌린지 21회차 미션 (0) | 2020.11.08 |
[패스트캠퍼스 수강 후기] 올인원 패키지 : 유니티 포트폴리오 완성 100% 환급 챌린지 20회차 미션 (0) | 2020.11.07 |
[패스트캠퍼스 수강 후기] 올인원 패키지 : 유니티 포트폴리오 완성 100% 환급 챌린지 19회차 미션 (0) | 2020.11.06 |