Data 관리

CJB_ny·2021년 11월 22일
0

// Data Manager #1 ~ Data Manager #2 까지 다 정리

1. Data Manager #1

data라고하면 1인 싱글플레이 게임의 경우

중간에 플레이 하다가 중간에 세이브를 했을때 세이브를 하는 파일을 생각하는 경우가 많은데

딱히 그런것을 말하는것은 아니고

게임내의 모든 "수치"들을 다 관리를 하는것을 말하는것이다.

예를들어 생각을 해보면

Player가 레벨1일때 체력이 100이였다가 레벨2면 체력이 200이되고 스택이 바뀌는 경우라던가

각 레벨별로 넘어가기위한 경험치도 수치와 관련이 있을것이고

각종 스킬의 데미지도 각종 수치와 관련이 있을것이고

몬스터의 AI라던가, 던전의 패턴같은 경우

게임에 존재하는 모든것을 다 데이터로 관리를 하게 될것이다.

근데 이것을 처음에 데이터로 관리를 하는것이 익숙치 않고 이상할 수 있다.

그런데 엄청 작은 게임을 만든다고 했을때는

그냥 어떤 스크립트에 하드코딩을 하여 다 만들어 놓는 것이 작업 속도가 빠를 순 있다.

클리커 게임이나, 러너게임의 수준의 게임이라고 하면은

굳이 데이터를 따로 뺴놔서 관리를 할 필요는 없기는 하다.

그런데 우리가 만약 하드코딩을 하였을때 코드에서 발생하는 "문제" 들에 대해서 생각을 해보자.

이렇게 하드코딩을 통하여 hp를 설정 해줄 수는 있지만

관리 차원에서 문제가 발생한다.

만약 벨런스나 그런부분이 안맞아서 고치고 싶다라고 할 때, 디자이너가 직접 고칠 수는 없고

프로그래머한테와서 일일히 고쳐달라고 해야될 것이다.

그래서 관리적인 차원에서도 문제가 되지만

더 큰 문제는,

우리가 만약에 이 게임을 출시를 했다고 가정을 해보자

배포를 하면은 실행파일로 만들어 줘가지고 윈도우든 ios, 안드로이드든 다른 기계에다가 다운을 받아서 사용을 하게 될텐데

이렇게 하드코딩된 파일든은 실행파일에 묶여서 들어가게된다.

그렇다는 것은 만약에 우리가 나중에 벨런스가 너무 안 맞아가지고 긴급 업데이트를 하고싶다라고 가정을 하면은

hp(코드) = 120(데이터); 애당초 이렇게 코드랑 데이터랑 묶여있기 때문에
( == 초기 수치가 코드에 박혀있기 때문에) 결국에는

배포를 다시 해가지고 바이너리가 다시 나간다음에( 바이너리가 뭐노??) 앱스토어에다가 다시 배포를 해야되는 문제가 발생한다..!!

그렇게되면 안드든 ios든 심사기간이 있으니까 굉장히 오래 걸린다.

그래서 하드코딩을 하지않고 대부분은 어떻게 하냐면은..

이런 hp = 120; 120과 같은 모든 수치와 관련된 데이터들은

별도의 파일로 일단 빼준다. 파일이라 하면 텍스트 파일도 되겠지만

일반적으로 사용되는것은 JSON이나 XML파일중 하나의 양식을 사용을 해서 들고 있게된다.

그래서 이렇게 파일을 들고있게되면

<장점>

  1. 나중에 게임을 실행할 때, 웹으로 이용해가지고 → 접근을 해서 → 웹통신을 이용해서

그 파일만 살짝 바꿔치기 해주면 나중에 게임이 실제로 실행되는 순간에는 그 바뀐 버젼으로 파일을 로드 하니까

모든 수치들이 바뀌어서 적용되게 될것이다.

그래서 나중에 라이브를 생각할 때, 관리 차원에서도 중요하게 생각해야된다.

  1. 나중에 서버랑 연동을 한다고 가정을 할 때,

우리가 클라이언트에서 생각하는 게임세상이랑 서버에서 생각하는 게임세상이랑은 "일치" 를 해야될것이다. 이게 무슨말인가 하면

서버에서는 레벨10짜리 유저의 hp가 300이라고 인식을 하는데, 클라이언트에서는 지멋대로 레벨10짜리 유져의 hp를 500이라고 인식을 하면은

서로 핀트가 안 맞는 문제가 발생 할 것이다.

그래서 데이터는 하나로 관리를 해가지고

나중에 서버랑 클라랑 똑같은 파일을 로드를 해가지고 게임 실행될 때 그 파일을 읽어서

메모리에 들고있는 형태로 무조건 만들어야 되는데

오늘은 그래서 이 작업을 해보는 시간을 가지도록 하겠다.

1-2. DataManager 코드 작성

일단, GameScene에서 이전에했던 코루틴과 관련된 작업들은 싹다 날려주자.

그리고 우리가 늘 하던대로 유니티에서
Managers산하에 스크립트 파일을 만들어 주도록하자.

자주했죠? 모노 날려주고

start(), update()날려주고

Managers에 가가지고

DataManager의 새로운 객체 _data를 만들어주고

전역으로 사용하고싶다면 public static DataManager Data { get { return Instance._data; } }

로 만들어 주자
(Managers 파일의 설명과 원리는 따로 빼 놓아서 정리 하였다)


init()하는부분도 까먹지 말고 해주도록하자.

참고로 데이터같은 경우에는 게임이 처음 실행되는 순간 다 로드 한다음에

씬이 바뀌더라도 굳이 clear할필요가 없다.


s_instance._data.init();

이녀석은 거의 대부분의 상황에서 거의 무조건 항상 들고있는다. ⇒ 용량이 엄청 크다고 볼 수도 없고..


그리고 Data Manager로 와가지고 init함수를 채워주기 전에 파일 포맷을 맞춰 줘야한다.

우리가 나중에 서버랑 클라랑 같은 파일을 사용할 것인데

보통 사용하는게 Json, XML 둘중에 하나 골라서 사용을 한다.

요즘에는 Json을 많이 사용하는거 같고 옛날 프로젝트의 경우 XML도 많이 사용을 한다.

1-3 Json, XML 설명

JSON, XML의 개념이 생소 할 수 있으니 잠시 설명하자면

employees라는 직원들을 관리하는 데이터가 있다고 가정을 햇을때

JSON, XML이 관리를 코드로 어떻게하는지 차이점을 보여준다

그런데 딱봐도 JSON이 더 우아해보인다 ⇒ 실제로 로딩속도도 더 빠르다(파싱할 것이 별로없다)

(파싱 == 파일을 읽는 작업)

그렇다고해서 XML의 장점이 없는 것은 아니다.

나중에 JSON의 데이터가 엄청 복잡해진다고 했을 때 XML은 계층 구조를 쉽게 파악할 수 있다는 장점이 있다.

나중에 5층 6층으로 파고들어서 파싱을 하는 경우가 있는데 이것을 JSON으로 보면은 진짜 보기가 어렵다.

그래서 JSON ⇒ 간략하게 표현할 때 좋고

XML은 표현력에 있어서는 우위이기는 한데, 속도 차원에서는 JSON이 더 좋다.

(참고로 최신 프로젝트는 거의다 Json으로 간다)

원본 파일들은 디자이너들이 엑셀파일로 가지고있는데

원본을 JSON으로 바꿔주는 툴을 만든다음에 결국 서버랑 클라에서는 JSON형식을 읽어가지고

사용하는 경우가 가장 많다.

그래서 우리도 이 JSON형식으로 작업을 진행 하도록 한다.

1-4 Json파일 만들고 추가하는 방법

이부분에서 파일을 로드해서 사용을 하기위해서는 일단 그 파일을 만들어 줘야한다.


먼저 Resource산하에 Data폴더 만들어준다.

모든 Data sheet를 여기 넣을것이다.


그런데 유니티에서 만들려고하니까 JSON형식이 없는데 이럴경우는 밖에 만들어서 넣어주면 된다.


Resource에서 Show in Explorer를 눌러주면

우리가 작업하는 Resource폴더 경로를 열어준다.

그리고 Data경로로 가서 StatData.txt로 만들어준다.

근데 지금 형식이 txt파일이다.

.json으로 바꿔주면된다.

그러면 이렇게 잘바뀜

그리고 창 닫고 유니티로 다시 와보면

이렇게 파일이 만들어 진것을 볼 수 있다.

Start(). Update() 다 지우고
창을 열고 이제 여기다가 뭔가를 넣어보도록 하자.

js를 공부를 했다면 좀 익 숙할 것이다.

구조체 안에 "stats" : [] 만들어 주고 레벨별로 스탯이 다 다를것이다.

이렇게 각 레벨별로 데이터를 하나하나씩 들고 잇을 것이다.

그리고 레벨3까지만 함 만들어 보자

이렇게
"stats" 안에 List를 만들어주고
각 List의 원소들은 Dict의 형태로
Key를 "level" : "1"이런식으로 들고있게 만들어 주도록하자.

이제 이것이 우리가 stat을 관리하는 데이터가 되는것이다.

그래서 게임이 시작할때 이것을 DataManger가 불러들여서 어딘가에다가 들고 있어야 할것이다.

그레서 이걸을 해보기 위해서

DataManager로 돌아가보록하자.

얘 같은 경우에는 TextAsset이 된다.

"" 여기다가 경로를 넣어줘야하는데 일단 하드코딩으로 넣어주도록하자.

.json은 안 적어주어도 알아서 잘 찾는다.

Managers.Resource.Load은

TextAsset을 뱉어주기 때문에 textAsset으로 받아주자

textAsset.text해보면 string으로 반환하는 것을 볼 수 있는데

테스트를 위해서 Log를 찍어보자

유니티에서 실행을 시켜보면

짤리는것은 길기 때문에 그런것이고, 잘 뜬다.

그래서 JSON파일을 쌩으로 Load하는 부분까지는 잘된다.

그래서 코드로 돌아가서 이것을 메모리에 들고 잇을 수 있도록 뭔가 변환 작업을 해줘야한다.

1-5 Json 파싱

그래서 JSON파일을 다시보면

stats라는 애가있고 이녀석이 List를 들고있는데

List안에 하나하나의 아이템들은

{
"level": "1",
"hp": "100",
"attack": "10"
},

이런 형식으로 되있다.

즉,

클래스로 이것을 좀 표현 해보자면

이렇게 표현 해 줄 수가 있는데 저 리스트의 stats의 이름은

현재 이부분의 stats를 나타내주게 될것이다.

그래서 결국 메모리 상에서는

이런 형식으로 들고있게 되는것이다.

그래서 이것을 이제 변환을 해주어야 한다.

그런데 c++같이 무식한 언어를 사용한다고 치면은

이녀석들을 한줄한줄 json파일을 파싱을 해가지고

여기다가 대입을 해준다.

그래서 한땀한땀 다 구현을 해주는 부분이 엄청 많다.

그런데 우리는 우월한 C#을 사용하기 때문에 Reflection기능을 활용하면된다.

먼저 [Serializable] 을 만들어주고 잠재적 수정사항 표시 해준다.

(그러면 using System; 뜨고 빨간줄 없어짐)

Serialize 랑 DeSerialize의 의미는 뭐냐하면은

이런식으로 메모리에서 들고있는것을

이런식으로 파일로 변환할 수 있다는 의미가 되는데

그것을 나타내주기위해서 [Serializable] 이런식으로 붙여주는데

[Serializable] 이거는 뭐 뭔지는 모르겠지만 공식처럼 붙여 줘야한다고 이해하면 되겠고

유니티에서 제공해주는 것이 있다(JSON파싱하는 것을)

JSON을 파싱하는것은 여러가지 방법이 있지만 워낙 자주 사용해서 유니티에서도 JSON을 파싱하는것을 제공한다.

JsonUtility. 을 찍어보면 FromJson, toJson이 있다.


ToJson은

이런식으로 class로 되있는데

Json형식으로 뭔가 변환하겠다라는 의미이고

FromJson은 그 반대의 의미이다.

그래서 이렇게 Json으로 된 string파일에서

이런

형식으로 변환을 해주겠다는것이 FromJson이고

(Json파싱 ⇒ class로 변환 == FromJson)

그래서 우리는 FromJson을 사용할 것이다.

FromJson<>안에다가는 우리가 변환하고 싶은 형식을 넣어준다.

변환하고싶은것이 StatData이니까

그래서

이렇게 넣어 줄 것이다.

그런데 FromJson은


사진과 같이

StatData를 반환하니까

이런식으로 data를 받아주도록하자.

그리고 궁금하니까


breakPoint를 여기 잡아주고 유니티실행 ㄱㄱ


캡쳐가 안되가지고 이런데

마우스 갖다 대면 뜬다

우리가 아무것도 안했는데

여기 있는 데이터가 다 들어가있다.

어떠한 형식이 될지 데이터의 포맷을 이렇게 맞춰주는것이다.

그리고 JsonUtility.FromJson 에서 DeSerialize를 해가지고

그러니까 "파일"에 있는것을 위에서처럼 메모리에 긁어오는 작업을 해가지고

여기에 있는 정보를 참조를 해서

public int level;
public int hp;
public int attack;

이렇게

public List stats = new List();

이렇게

한번에 그것을 맞춰가지고 불러 온것으로 보면된다!

2. Data Manager #2

Reflection의 중요성을 설명했다

우리가 reflection을 사용을했는데 c++에서는 엄청나게 귀찮은 작업인데 Csharp에서는 reflection기능을 제공하기 때문에 엄청 편하다라는 대충 그런말이다.

2-1. 주의할 점

하나 중요한것이

여기에서 level, hp, attack 이렇게 public으로 선언했는데 이 변수명들이

Json파일에서 변수명과 다르면 찾지를 못한다.

그래서 반드시


이 이름이랑

이 이름이랑 똑같이 맞춰 줘야한다.

또한

현재 int형인데

Json의 "1" 부분도 자동으로 int형으로 파싱을 해줄 것이다.

만약 public class Stat

public int level이렇게했는데

hello나 이렇게 해버리면 로딩하는 순간에 뻑 날것이다.

그래서 json에서 데이터를 맞춰주고

클래스를 맞춰 주면은 한번에 변형이 된다.

**만약 문제가 있다고 한다고 치면은 프로그램을 키는 순간에 바로 죽어버리기 때문에

죽은 것을 보고 어디가 문제인지 찾아서 고치면 된다.**

2-2. Dictionary로 data관리하기

그래서 이제 그 다음에 해야할것은


data를 이렇게 불러왔으니까

이 data를 DataManager가 들고 있게 끄름 만들어 줘야한다.

하지만 지금 같은 경우에는 데이터가 엄청 작기 때문에


이렇게 StatData data를 위에다가 선언을 하고
밑에서 data = 이런식으로물고 있게 해도 큰 문제는 없다.

하지만 대부분의 경우에는 (Stat의 경우에는 예외적이고)

id가 들어 간다!
예를 들자면은


이부분이 Stat이 아니라 몬스터나 NPC의 정보를 나타내는 부분이라고 하면은

NPC나 몬스터는 그 녀석을 식별하기위한 id를 하나 들고있게되는데 그것은 데이터 sheet에 있는 고유의 아이디가 되는것이다.

오크라는 녀석은 id를 3번으로 구현을해서 애들 하나하나 아이디를 부여를 해서 사용하게 된다.

그래서 만약 위에서 설명한 id를 부여해서 사용했다라고 가정을 하면은

이런식으로 List로 들고 잇는것은 비효율적이다. (하나하나 다 찾아야 하기때문에 ⇒ 자료구조적 관점에서)

List같은 경우에는 특정 id를 찾고 싶을 때, 모든 값을 다 순회를 해보는 방법 밖에 없다.


그래서 DataManager의 경우에는 Dictioary형태로 가지고 있는 것이 훨씬 더 많다.

이런식으로 Dict를 만들어 줄 수 있겠다.

그래서

Dict의 Key값에는 public int level이 들어가고 해당 레벨의 stat을 빠르게 찾아주면 될것이다.

그래서 이부분이 Stat이 아니라 몬스터나 NPC일 경우 작업을 효율이 올라가니까

이부분을 구현하는 작업을 해보자.

그래서 다시

바깥에서 물지않고 안쪽에 다시 물어주는 형태로 만들어 준다음에

이렇게 해주고

data를 변환 작업을 해주면된다.

data.stats가 List형식으로 되있으니까

List → Dict 변경해줘야함

data를 변환 작업을 해주면된다. ⇒ List를 Dict로 변경하는 방법은 여러가지인데

ToDictionary를 사용할 수도 있는데 Linq라는 기능을 이용하고 있다.

이것이 예전에는 링크가 IOS쪽에서 버그가 굉장히 많아서 잘 사용을 안하는 추세였다.

그래서 사용하기 꺼림찍하니까 수동으로 그냥 넣어주자

data.stats을 돌면서

key는 stat.level로 해주고 value는 해당 stat자체를 넣어주면 될것이다.

그러면 level넣으면 해당 stat이 나올것이다(찾을때)

그래서 유니티 연결해서 breakpoint잡고 실행하면

현재 캡처가 안되는데 StatDict에 마우스 갖다 대면 안에 key, value형식으로 잘 들어가있는것을 확인 할 수 있다.

그래서 key값으로 바로 접근 할 수 있도록 잘 준비가 되어있다.

그래서 나중에 NPC든 퀘스트든 아이디를 부여해가지고 그 아이디로 빠르게 정보를 추출 할 수 있게 만든 것이다.

그래서 이까지 했다면 대충 틀은 잡기는 한것이다.

2-3 하드코딩 수정 + 인터페이스 만들기

그런데,

우리가 한것은 문제가 너무 하드코딩이 많이 들어간다는 것이다.

그래서 어떻게 관리를 할것이냐가 문제 인데..

일단 중요한것이

여기서 key값과 value값이 매번 다르다는 것이다

public Dictionary<int, Stat> int, Stat이 안들어가고 다른것이 들어 갈 수 있다는 뜻이다.

StatDict가 아니라 NPCDict를 만들어야 한다고 가정을 한다면 key값을 int일 수도 있지만 string으로 찾을 수도 있는것이고, 그냥 키, value타입은 우리가 늘리는 Dict의 타입에 따라 왔다갔다 할것이다.

그리고 init에서도 매번 경로를 받아와서 Load하는 부분도

다를 수 있기 때문에

위에 말한 두가지 부분을 좀 수정을 해보도록 하자.

그래서 인터페이스를 하나 만들어 주도록하자

데이터를 로드하는 인터페이스인데

먼저 데이터를 로딩한다는 느낌으로 ILoader를 만들고

<Key, Value>타입을 가지고 있을텐데,

그리고 이 인터페이스를 적용한 녀석은 반드시

Dictionary<Key, Value>인데 반드시 Key, Value를 뱉어주는

Dictionary<Key, Value> MakeDict(); MakeDict()라는 녀석을 반드시 구현해야한다.라는 ILoader라는 인터페이스를 하나 만들었다.

그리고 StatData : ILoader<int, Stat>을 상속받게(인터페이스를 상속받게 만들어준다)

빨간줄이 뜨는 이유는 인터페이스를 구현하지 않아서 그렇다.

이렇게 인터페이스 구현을 해주도록 하자.

그래서 이제는 MakeDict라는 녀석을 반드시 뱉어주도록 만든 것이다.

그래서 우리가 이제 밑줄친

여기에서 변환 하는 부분을 넣어 주어야 될것이다.

foreach (Stat stat in data.stats)
StatDict.Add(stat.level, stat);
이부분을 저기 밑줄에 넣어 주어야 할 것이다.

그래서 복붙해서 넣어준다음에

임시로 사용할 dict만들어준다.


그리고


data.stats에 빨간줄 떠있는데 왜 떠있는지 생각해봐바

지금 [Serializeable]로 Json데이터의 형식을 맞춰 줬다. Json의 stats는 배열인데 그 배열을 지금 stats가 형식을 맞춰주어서 그대로 글고있기 때문에

foreach안에서 Stat stat in data.stats가 아니라 Stat stat in stats가 되어야한다.

요렇게

그레서 변환하는 작업만 이렇게해주고

경우에 따라서만 직접 입력을 해주면 될것이다.

혹시나 여기서 validate를 하고싶다(체크를 하고싶다고하면 MakeDict()안에서 뭔가 코드를 추가를 하면 될거같고,

일단 MakeDict가 구현이 되었으니까 밑에서 사용을 할 수가 있는데...

init하는 부분 수정하는데

함수를 하나 만들어 주도록하자

Loader, Key, Value라는 3개의 Generic타입을 넣어주고 인자로는 파일의 경로를 넣어 주도록 만들자.

그리고

where Loader : ILoader<Key, Value> ⇒ Loader는 반드시 ILoader인터페이스를 상속받은 애여아 하는데 ILoader<Key, Value> 인 이유는

ILoader인터페이스를 만들때 Generic 타입으로 만들었기 때문에 똑같이 <Key, Value>로 해준다.

그래서

이부분이 조금 햇갈릴 수 있는데 그냥

Key, Value를 반드시 지니고 있는 ILoader를 LoadJson은 상속받아야 한다는 것이다.

그래서 init에 있던

이 부분을 LoadJson에 가지고 올것이다.

textAsset을 가져오는 부분은 똑같은데, 다만

$"Data/StatData" 이렇게 하드 코딩이 된것이 아니라

$"Data/{path}"이렇게 될것이다.

또한

textAsset의 text를 받아오는것까지는 똑같은데

밑줄친 부분 StatData로 하드 코딩이 된것이 아니라

FromJson로 바뀔것이다.

요렇게

그래서 Loader data부분은 바로 반환을 해주면 되는 부분이라서

이렇게 바로 return을 때려 줄 것이다.

그래서

Loader LoadJson<Loader, Key, Value>(string path) where Loader : ILoader<Key, Value>

{ }

이렇게 만들어 주는 부분이 좀 어렵지

StatDict = LoadJson<StatData, int, Stat>("StatData").MakeDict();이렇게 사용하는 부분은 어렵지는 않다.

int은 Key타입, Stat는 Value타입, 그리고 전체를 들고있는 StatData는

이녀석 전체를 넣어 준것이 된다.

그래서 일단 이렇게 만들어 주었는데

<문제>가 다시 하나 발생한다.

2-4. 데이터 따로 관리

만약 데이터가 늘어 난다고 가정을 한다면은...

이러한 애들을 DataManager산하에서 관리를 한다면 좀 버거울 것이다.

나중에 가면은 이러한 애들이 어마어마하게 늘어 날것이기 때문이다.

그래서 여기서 들고있는것 보다는 다른 파일에 들고 있으면서 관리를 하자!

그래서 유니티에서 Script폴더 산하에 data만 전문적으로 관리할 폴더를 만들어 주자

그리고 Data폴더 산하에 Data.Contents스크립트 파일 만들어주자

Data.Contents 쩜을 찍어서 만드는 이유는

나중에 이 데이터 녀석을 Contents로 사용할 것인지, 아니면 뭐 AI관련되있는 것인지에 따라서 그냥 이름을 구분해준 것이다.

(지금은 Contents와 관련된 애니까 이렇게 지어서 만듬)

(오른쪽에 에러는 Data. 쩜을 찍어서 불평을 하는부분은데 어차피 이 파일안에는 클래스는 필요 없으니 다 날려 준다. 클래스에 . 쩜을 찍어서 불평을 하는데 파일에는 쩜을 찍어도 아무 문제가 없다.)

안에 다 지워주고

DataManager에 있던

[Serializable]
public class Stat
{
public int level;
public int hp;
public int attack;
}

[Serializable]
public class StatData : ILoader<int, Stat>
{
public List stats = new List();

public Dictionary<int, Stat> MakeDict()
{
    Dictionary<int, Stat> dict = new Dictionary<int, Stat>();

    foreach (Stat stat in stats)
        dict.Add(stat.level, stat);

    return dict;
}

}

이녀석들을

이쪽으로 이렇게 이사를 시켜주도록하자.

그리고 이 데이터들도 늘어나면 관리가 힘들테니 region으로 묶어 주도록 하자.

이렇게

그러면 이렇게 접었다가 필 수도 있고 아주 짱짱맨이다.

2-5. 데이터 사용하기

그래서 스크립트 산하에 데이터들은 어떻게

이 파일

format을 불러 읽어 들일지를 나타내는 부분이라 할 수 있다.

그리고 실제로 그 파일을 불러 읽어들이는 부분은

DataManager에서

StatDict = LoadJson<StatData, int, Stat>("StatData").MakeDict(); 이녀석이랑

public Dictionary<int, Stat> StatDict { get; private set; } = new Dictionary<int, Stat>(); 이녀석만 이제 계속 추가를 해줘가지고

데이터를 넣어주면 될것이다.

그래서 이제 외부에서 데이터를 사용을 하려면은

StatDict만 뽑아서 사용을 하면된다.

GameScene에 가가지고

이녀석을 불러온다.

예를들어 컨텐츠 코드에서 2레벨이 됬는데 그때 해당하는 hp가 얼마인지 알고싶다.라고 하면은 이제 이녀석을 참조를 하면될 것이다.

Dictionary<int ,Stat> 으로 뱉어주니

똑같이 형식 맞춰준다음 Dictionary<int, Stat> dict로 받아주면 될것이다.

그리고 확인을 위해서

17에 breakPoint를 잡고 유니티연결 → 유니티에서 게임씬에서 실행 하고

visual code에서 dict에 마우스 갖다대면 key, value등등 값 제대로 다 들어가 있는 것을 확인할 수 있다.

그래서 이제 이런식으로 데이터를 관리를 하기 시작하는 것이다.

2-6. 정리

나중에 우리가 게임에 존재하는 모든 데이터들은 이렇게 Json파일로 따로 뺴놓아서 관리를 하게될것이고

보통은 이렇게 분리를 하게하니까 보통은 디자이너 분들이 데이터 파일을 건드리게 될것이고

우리는 이 코드부분에서만 신경을 써주면 될것이다.

이제 이렇게해서 데이터랑 코드를 분리하는 것 까지 해보았고요

이제 C#서버 연동까지 배우게되면 방금만든 Json파일을 불러 읽어들이는 부분을 서버쪽에서도 넣어두어야한다. 그러면 모두 같은 데이터를 보고있으니까

모든 게임세상이 아름답게 잘 돌아 간다.

그리고 참고로 경우에 따라서 클라랑 서버랑 공용으로 읽어들이는 파일이랑

서버 전용으로 사용할 파일을 구분하기도 한다.

왜냐하면 강화 확률 같은 부분은 사실 데이터로 이렇게 공용으로 다 보여주면은 혹시라도 누군가가 데이터를 까보면은 그 확률을 다 알 수 있으니까 대부분 그렇게 은밀하게 관리해야하는 것들은

따로 빼놓아서 서버에서 따로 불러 읽어들이도록 관리하는 부분이 많다.

아무튼 이렇게

구현한것은 얼마 되지 않았다.

(따로 별개로 내가 이해를 하는데 시간이 좀 걸렸다)

이렇게 해서 거의 모든 필수 적인 기능들은 다 들어갔다.

그리고 지금까지했던 모든 Manager들이나 기능들은 2D게임이든 3D게임이든 다 필수적으로 공통으로 들어가는 부분들이다.

그래서 이제 앞으로 부터가 길이 좀 갈린다.

내가 "2D 게임을 만들고 싶다" ,"3D게임을 만들고 싶다"에 따라가지고 조금씩 공부하는것이 달라 질텐데

그래서 이까지 유니티엔진에 대한 기초적이고 필수 적인 내용들에 대해서 알아 보았다.

그리고 어떤 게임을 만들고싶은지는 모르겠지만 앞으로 개발을 할 때

빈프로젝트에서 처음부터 다 쌓아 올려서 만들지 말고

이런 본인만의 프레임워크를 만든다음에 그것을 기반으로 쌓아 올려 만들면 훨씬 빠르게 개발을 할 수 가 있다.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글