일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 유니티
- 프로그래머스
- 3월
- 입문
- 1월
- 2025년
- C/C++
- 2022년
- 10월
- 다이나믹 프로그래밍
- 단계별로 풀어보기
- c++
- 유니티 심화과정
- 코딩 테스트
- 수학
- 2023년
- 개인 프로젝트
- 7월
- 5월
- 코딩 기초 트레이닝
- 개인 프로젝트 - 런앤건
- 게임 엔진 공부
- 4월
- 기초
- todolist
- 2월
- 골드메탈
- 자료 구조
- 백준
- 2024년
- Today
- Total
기록 보관소
[Unity/유니티] 기초-탑다운 2D RPG: 대화 시스템 구현하기[B23] 본문
개요
유니티 입문과 독학을 위해서 아래 링크의 골드메탈님의 영상들을 보며 진행 상황 사진 또는 캡처를 올리고 배웠던 점을 요약해서 적는다.
현재는 영상들을 보고 따라하고 배우는 것에 집중할 것이며, 영상을 모두 보고 따라한 후에는 개인 프로젝트를 설계하고 직접 만드는 것이 목표다.
https://youtube.com/playlist?list=PLO-mt5Iu5TeYI4dbYwWP8JqZMC9iuUIW2
유니티 강좌 기초 채널 Basic
유니티 개발을 처음 시작하시는 입문자 분들을 위한 기초 채널. [ 프로젝트 ] B00 ~ B12 (BE1) : 유니티 필수 기초 B13 ~ B19 (BE2) : 2D 플랫포머 B20 ~ B26 (BE3) : 2D 탑다운 대화형 RPG B27 ~ B37 (BE4) : 2D 종스크롤
www.youtube.com
탑다운 2D RPG: 대화 시스템 구현하기[B23]
1. 오브젝트 관리
//ObjData 스크립트 파일
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjData : MonoBehaviour {
public int id;
public bool isNPC;
}
- 간단하게 오브젝트의 id와 NPC인지 구분하는 변수 2개만 만들어서 설정했다. 일반 오브젝트는 100번대 id, NPC는 1000번대 id에 isNPC를 체크해두었다.
2. 대화 시스템
//TalkManager 스크립트 파일
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TalkManager : MonoBehaviour {
Dictionary<int, string[]> talkData;
void Awake () {
talkData = new Dictionary<int, string[]>();
GenerateDate();
}
void GenerateDate () {
talkData.Add(1000, new string[] { "안녕?", "이 곳에 처음 왔구나?" });
talkData.Add(1001, new string[] { "안녕!", "오늘 날씨가 정말 좋지?" });
talkData.Add(100, new string[] { "평범한 나무 상자다." });
talkData.Add(101, new string[] { "누군가 사용했던 흔적이 있는 책상이다." });
}
public string GetTalk(int id, int talkIndex) {
if (talkIndex == talkData[id].Length)
return null;
else
return talkData[id][talkIndex];
}
}
//GameManager 스크립트 파일
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour {
public TalkManager talkManager;
public GameObject talkPanel;
public Text talkText;
public GameObject scanObject;
public bool isAction; //대화창 활성화 여부 체크
public int talkIndex;
public void Action (GameObject scanObj) {
scanObject = scanObj;
ObjData objData = scanObject.GetComponent<ObjData>();
Talk(objData.id, objData.isNPC);
talkPanel.SetActive(isAction);
}
void Talk(int id, bool isNPC) {
string talkData = talkManager.GetTalk(id, talkIndex);
if (talkData == null) {
isAction = false;
talkIndex = 0;
return;
}
if (isNPC) {
talkText.text = talkData;
}
else {
talkText.text = talkData;
}
isAction = true;
talkIndex++;
}
}
- 이전까지 대화창은 그냥 스프라이트 이름을 출력하고, 별도의 대화나 조사가 아니었다. 그래서 GameManager에서 스페이스바를 통해 레이어가 Object일때만 isAction이 true가 되어 스프라이트의 이름이 출력되고, 다시 누르면 isAction이 false가 되면서 꺼지는 방식이었다.
- 이번 시간에는 대화를 직접 사용자가 입력하고 저장할 TalkManager를 만들었으니, 여기에서 해당 오브젝트의 ID와 대화 내용을 저장하고, 대화 내용이 모두 출력될 때까지 isAction이 true가 되도록한다. 대화 내용은 문자열 배열의 인덱스를 활용했다.
- Dictionary<TKey, TValue> : 데이터 구조가 key와 연결된 value값이 필요하다. 그래서 제네릭에 두가지 데이터 타입이 필요하다.
- .Add(key, value) : 데이터 추가
3. 초상화
//TalkManager 스크립트 파일
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TalkManager : MonoBehaviour {
Dictionary<int, string[]> talkData;
Dictionary<int, Sprite> portraitData;
public Sprite[] portraitArr;
void Awake () {
talkData = new Dictionary<int, string[]>();
portraitData = new Dictionary<int, Sprite>();
GenerateDate();
}
void GenerateDate () {
talkData.Add(1000, new string[] { "안녕?:0", "이 곳에 처음 왔구나?:2", "저기 있는 집은 루나네 집이야.:1" });
talkData.Add(2000, new string[] { "안녕!:0", "오늘 날씨가 정말 좋지?:2" });
talkData.Add(100, new string[] { "평범한 나무 상자다." });
talkData.Add(200, new string[] { "누군가 사용했던 흔적이 있는 책상이다." });
portraitData.Add(2000 + 0, portraitArr[0]); //Luna Idle
portraitData.Add(2000 + 1, portraitArr[1]); //Luna Talk
portraitData.Add(2000 + 2, portraitArr[2]); //Luna Smile
portraitData.Add(2000 + 3, portraitArr[3]); //Luna Angry
portraitData.Add(1000 + 0, portraitArr[4]); //Ludo Idle
portraitData.Add(1000 + 1, portraitArr[5]); //Ludo Talk
portraitData.Add(1000 + 2, portraitArr[6]); //Ludo Smile
portraitData.Add(1000 + 3, portraitArr[7]); //Ludo Angry
}
public string GetTalk(int id, int talkIndex) {
if (talkIndex == talkData[id].Length)
return null;
else
return talkData[id][talkIndex];
}
public Sprite GetPortrait(int id, int portraitIndex) {
return portraitData[id + portraitIndex];
}
}
//GameManager 스크립트 파일
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour {
public TalkManager talkManager;
public GameObject talkPanel;
public Image portraitImg;
public Text talkText;
public GameObject scanObject;
public bool isAction; //대화창 활성화 여부 체크
public int talkIndex;
public void Action (GameObject scanObj) {
scanObject = scanObj;
ObjData objData = scanObject.GetComponent<ObjData>();
Talk(objData.id, objData.isNPC);
talkPanel.SetActive(isAction);
}
void Talk(int id, bool isNPC) {
string talkData = talkManager.GetTalk(id, talkIndex);
if (talkData == null) {
isAction = false;
talkIndex = 0;
return;
}
if (isNPC) { //NPC라면
talkText.text = talkData.Split(':')[0];
portraitImg.sprite = talkManager.GetPortrait(id, int.Parse(talkData.Split(':')[1]));
portraitImg.color = new Color(1, 1, 1, 1); //초상화 보이기
}
else { //NPC가 아니라면
talkText.text = talkData;
portraitImg.color = new Color(1, 1, 1, 0); //초상화 투명화
}
isAction = true;
talkIndex++;
}
}
- 초상화는 NPC당 총 4개(Idle, Talk, Smile, Angry)의 스프라이트가 있다. 그래서 TalkManager에 각 스프라이트들을 모두 넣어두고, NPC 대사에 콜론(:)과 인덱스를 넣어 해당 대사에 어울리는 감정 표현의 초상화를 출력하도록 만들었다.
- .Split() : 구분자를 통하여 배열로 나눠주는 문자열(string) 함수. 배열로 나눠주기때문에 사용할때는 뒤에 [0]처럼 배열 인덱스를 넣어줘야한다.
- 데이터 타입.Parse() : 문자열을 해당 타입으로 변환해주는 함수. 위 코드에서는 int형으로 변환했다. 문자열 내용이 타입과 맞지않으면 오류가 발생하므로 주의해야한다.
- 참고로 원활한 진행을 위해서 Luna와 Desk의 오브젝트 id를 1001에서 2000으로 바꾸고, 101에서 200으로 바꾸었다.
'유니티 프로젝트 > 탑다운 2D RPG' 카테고리의 다른 글
[Unity/유니티] 기초-탑다운 2D RPG: 대화 애니메이션 느낌있게 만들기[B25] (0) | 2022.02.21 |
---|---|
[Unity/유니티] 기초-탑다운 2D RPG: 퀘스트 시스템 구현하기[B24] (0) | 2022.02.20 |
[Unity/유니티] 기초-탑다운 2D RPG: 대화창 UI 구축하기[B22] (0) | 2022.02.18 |
[Unity/유니티] 기초-탑다운 2D RPG: 쯔꾸르식 액션 구현하기[B21] (0) | 2022.02.17 |
[Unity/유니티] 기초-탑다운 2D RPG: 도트 타일맵으로 쉽게 준비하기[B20] (0) | 2022.02.17 |