일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 연습
- ChatGPT
- 오브젝트 풀링
- OVR
- XR
- 개발
- 길건너 친구들
- Oculus
- 유니티 GUI
- input system
- 유니티 UI
- 포트폴리오
- 오큘러스
- HAPTIC
- 유니티 Json 데이터 연동
- 가상현실
- 멀티플레이
- 유니티
- 팀 프로젝트
- meta
- VR
- 모작
- CGV
- Photon Fusion
- 팀프로젝트
- 드래곤 플라이트 모작
- 개발일지
- 드래곤 플라이트
- 앱 배포
- meta xr
- Today
- Total
EasyCastleUNITY
유니티 데이터 연동 본문
사용할 asset들 제작
썸네일 제작
여기서 썸네일이 들어갈 적당한 frame 찾기
포토샵에서 ctrl + shift + alt + S 해서 각각 따로 저장
데이터 json 화
https://shancarter.github.io/mr-data-converter/
을 통해 json으로 변화
json 파일
[
{
"id": "100",
"name": "Alien",
"max_hp": "100",
"damage": "5",
"prefab_name": "AlienDefault",
"sprite_name": "thumb_alien"
},
{
"id": "101",
"name": "Bear",
"max_hp": "110",
"damage": "10",
"prefab_name": "BearDefault",
"sprite_name": "thumb_bear"
},
{
"id": "102",
"name": "Chemicalman",
"max_hp": "120",
"damage": "15",
"prefab_name": "ChemicalmanDefault",
"sprite_name": "thumb_chemicalman"
},
{
"id": "103",
"name": "Cowboy",
"max_hp": "140",
"damage": "20",
"prefab_name": "CowboyDefault",
"sprite_name": "thumb_cowboy"
},
{
"id": "104",
"name": "Jester",
"max_hp": "150",
"damage": "25",
"prefab_name": "JesterDefault",
"sprite_name": "thumb_jester"
}
]
유니티에서 읽어오기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class App : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
TextAsset aseet = Resources.Load<TextAsset>("Data/hero_data"); //json은 안 붙임
Debug.Log(aseet);
}
}
패키지 매니저에서
com.unity.nuget.newtonsoft-json
Json 파일 역직렬화
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeroData //정보 저장용 스크립트
{
//id name max_hp damage prefab_name sprite_name
//int string int float string string
public int id;
public string name;
public int max_Hp;
public float damage;
public string prefab_name;
public string sprite_name;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using UnityEditor.VersionControl;
public class App : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
TextAsset aseet = Resources.Load<TextAsset>("Data/hero_data"); //json은 안 붙임
Debug.Log(aseet);
//역직렬화
HeroData[] heroDatas = JsonConvert.DeserializeObject<HeroData[]>(aseet.text);
foreach (HeroData data in heroDatas)
{
Debug.LogFormat("{0} {1} {2} {3} {4} {5}", data.id, data.name, data.max_Hp, data.damage, data.prefab_name, data.sprite_name);
}
}
}
버튼에 따라서 다른 종류의 Hero 생성
전에 생성된 Hero는 지워진다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using UnityEditor.VersionControl;
using System;
using UnityEngine.UI;
public class App : MonoBehaviour
{
[SerializeField] private List<Button> btns;
//프리팹이 저장될 변수
public List<GameObject> prefabs = new List<GameObject>();
//생성된 객체가 저장될 변수
private GameObject go;
private GameObject hero;
//생성된 객체의 id가 저장될 변수
int goId = 0;
int id = 0;
// Start is called before the first frame update
void Start()
{
//데이터 로드
DataManager.instance.LoadHeroDatas();
//프리팹 리소스 로드
this.LoadPrefabs();
foreach (Button btn in btns)
{
btn.onClick.AddListener(() => {
//자식의 text 저장
string id = btn.GetComponentInChildren<Text>().text;
//int로 변경
this.id = Convert.ToInt32(id);
//저장된 id를 통해 영웅 생성
this.MakeHero(this.id);
});
}
}
private void LoadPrefabs()
{
List<string> heroPrefabNames = DataManager.instance.GetHeroPrefabNames();
foreach(string prefabName in heroPrefabNames)
{
string path = string.Format("Prefabs/{0}", prefabName);
Debug.Log(path);
GameObject prefab = Resources.Load<GameObject>(path);
this.prefabs.Add(prefab);
}
Debug.LogFormat("프리팹들이 로드 되었습니다. Count:{0}",this.prefabs.Count);
}
private void MakeHero(int id)
{
if(this.go == null) //생성이 처음이면
{
this.hero = new GameObject("Hero"); //Hero라는 이름의 GameObject 생성
this.go = Instantiate(prefabs[id - 100]);
this.go.transform.SetParent(hero.transform);
goId = id;
Debug.LogFormat("id: {0} 객체 생성", this.goId);
}
else
{
Destroy(this.go);
this.go = Instantiate(prefabs[id - 100]);
this.go.transform.SetParent(hero.transform);
goId = id;
Debug.LogFormat("id: {0} 객체 생성", this.goId);
}
}
}
파일이 있으면 기존유저, 없으면 신규유저(데이터 저장과 불러오기는 직렬화와 역직렬화 이용)
DataManager ->Resources에서 json 파일을 읽어온다.
옆에 사진은 Resources 파일의 현화
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class DataManager
{
//싱글톤
public static readonly DataManager instance = new DataManager();
// 키/값
private Dictionary<int, HeroData> dicHeroDats = new Dictionary<int, HeroData>();
//생성자
private DataManager()
{
}
public void LoadHeroDatas()
{
TextAsset aseet = Resources.Load<TextAsset>("Data/hero_data"); //json은 안 붙임
//역직렬화
HeroData[] heroDatas = JsonConvert.DeserializeObject<HeroData[]>(aseet.text);
foreach (HeroData data in heroDatas)
{
Debug.LogFormat("{0} {1} {2} {3} {4} {5}", data.id, data.name, data.max_Hp, data.damage, data.prefab_name, data.sprite_name);
this.dicHeroDats.Add(data.id, data);
}
Debug.LogFormat("HeroData 로드 완료 :{0}", dicHeroDats.Count);
}
public HeroData GetHeroData(int id)
{
return dicHeroDats[id];
}
public List<string> GetHeroPrefabNames()
{
List<string> list = new List<string>();
foreach(HeroData data in this.dicHeroDats.Values) //저장된 사전의 value값은 HeroData들
{
list.Add(data.prefab_name);
}
return list;
}
public List<string> GetHeroSpriteNames()
{
List<string> list = new List<string>();
foreach(HeroData data in this.dicHeroDats.Values)
{
list.Add(data.sprite_name);
}
return list;
}
public List<HeroData> HeroDatas()
{
return this.dicHeroDats.Values.ToList();
}
}
HeroData: 정보들을 저장하는 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeroData //정보 저장용 스크립트
{
//id name max_hp damage prefab_name sprite_name
//int string int float string string
public int id;
public string name;
public int max_Hp;
public float damage;
public string prefab_name;
public string sprite_name;
}
HeroInfo: 객체의 id와 변하는 데이터들을 저장하는 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeroInfo
{
public int id;
//변하는 데이터
public float hp;
public float damage;
//생성자
public HeroInfo(int id, float hp, float damage)
{
this.id = id;
this.hp = hp;
this.damage = damage;
}
}
App: 실제 실행 부분
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using UnityEditor.VersionControl;
using System;
using UnityEngine.UI;
using System.IO;
using UnityEngine.U2D;
public class App : MonoBehaviour
{
[SerializeField] private List<Button> btns;
//프리팹이 저장될 변수
public List<GameObject> prefabs = new List<GameObject>();
[SerializeField]
private SpriteAtlas atlas;
[SerializeField]
private UISlot[] uiSlots;
[SerializeField] private Button loadBtn;
//생성된 객체가 저장될 변수
private GameObject heroModel;
private GameObject heroGo;
private HeroInfo heroInfo;
private Hero hero; //실제 영웅 객체
//생성된 객체의 id가 저장될 변수
int goId = 0;
int id = 0;
// Start is called before the first frame update
void Start()
{
//데이터 로드
DataManager.instance.LoadHeroDatas();
//프리팹 리소스 로드
this.LoadPrefabs();
//슬롯 초기화
List<HeroData> heroDatas = DataManager.instance.HeroDatas();
for(int i=0; i<heroDatas.Count;i++)
{
UISlot slot = this.uiSlots[i];
HeroData data = heroDatas[i];
Sprite sprite = this.atlas.GetSprite(data.sprite_name);
slot.onClick = (id) => {
this.CreateHero(id);
};
slot.Init(data.id, sprite);
}
string filePath = string.Format("{0}/hero_info.json", Application.persistentDataPath);
loadBtn.onClick.AddListener(() => {
if(this.heroGo == null)
{
string json = File.ReadAllText(filePath);
HeroInfo heroInfo = JsonConvert.DeserializeObject<HeroInfo>(json);
this.heroGo = new GameObject("Hero");
this.heroModel = Instantiate(prefabs[heroInfo.id - 100], this.heroGo.transform);
this.hero = this.heroGo.AddComponent<Hero>();
this.CreateHero(heroInfo.id);
}
});
if (File.Exists(filePath)) //있다, 기존유저
{
Debug.Log("기존유저");
for (int i = 0; i < 5; i++)
{
uiSlots[i].gameObject.SetActive(false);
}
this.loadBtn.gameObject.SetActive(true);
}
}
private void LoadPrefabs()
{
List<string> heroPrefabNames = DataManager.instance.GetHeroPrefabNames();
foreach(string prefabName in heroPrefabNames)
{
string path = string.Format("Prefabs/{0}", prefabName);
Debug.Log(path);
GameObject prefab = Resources.Load<GameObject>(path);
this.prefabs.Add(prefab);
}
Debug.LogFormat("프리팹들이 로드 되었습니다. Count:{0}",this.prefabs.Count);
}
private void CreateHero(int id)
{
//Info 만들기
//신규 유저일 경우 새로운 HeroInfo 객체를 만들고
//기존 유저일 경우, hero_info.json파일을 로드해서 역직렬화 해서 HeroInfo 객체를 만든다.
//저장위치
//Application.persistentDataPath
string filePath = string.Format("{0}/hero_info.json", Application.persistentDataPath);
// C:/Users/user/AppData/LocalLow/DefaultCompany/SaveAndLoad
if (File.Exists(filePath)) //있다, 기존유저
{
Debug.Log("기존유저");
}
else
{
//신규유저
Debug.Log("신규유저");
this.loadBtn.gameObject.SetActive(false);
HeroData heroData = DataManager.instance.GetHeroData(id);
heroInfo = new HeroInfo(heroData.id, heroData.max_Hp, heroData.damage);
this.CreateModelAndGo(id);
string json = JsonConvert.SerializeObject(this.hero.GetInfo());
Debug.LogFormat("<color=yellow>저장되는 json:{0}</color>", json);
File.WriteAllText(filePath, json);
}
//HeroController 컴포넌트에 model과 info를 넘겨야 함
}
private void CreateModelAndGo(int id)
{
//--------------------------모델 생성---------------------------------
if (this.heroModel == null) //생성이 처음이면
{
this.heroGo = new GameObject("Hero"); //Hero라는 이름의 GameObject 생성
this.heroModel = Instantiate(prefabs[id - 100]);
this.heroModel.transform.SetParent(heroGo.transform);
this.hero = heroGo.AddComponent<Hero>();
//HeroController 컴포넌트에 model과 info를 넘겨야 함
hero.Init(heroInfo, heroModel);
goId = id;
Debug.LogFormat("id: {0} 객체 생성", this.goId);
}
else
{
//Destroy(this.model);
//this.model = Instantiate(prefabs[id - 100]);
//this.model.transform.SetParent(heroGo.transform);
//goId = id;
//Debug.LogFormat("id: {0} 객체 생성", this.goId);
Debug.LogFormat("<color=red>id : {0} 영웅이 있어 만들 수 없습니다</color>", this.goId);
}
}
}
Hero: 영웅들의 정보와 model에 대한 정보를 받아 저장한다. 실제 영웅 오브젝트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Hero : MonoBehaviour
{
//영웅의 정보와, model에 대한 정보를 init으로 저장하고 있다.
private HeroInfo heroInfo;
private GameObject model;
public void Init(HeroInfo heroInfo, GameObject model)
{
this.heroInfo = heroInfo;
this.model = model;
Debug.LogFormat("Init:{0}, {1}", this.heroInfo, this.model);
}
public HeroInfo GetInfo()
{
return this.heroInfo;
}
}
UISlot -> 슬롯에 대한 정보를 저장하는 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UISlot : MonoBehaviour
{
private int id;
public System.Action<int> onClick;
[SerializeField]
private Button btn;
[SerializeField]
private Image img;
public void Init(int id, Sprite sp)
{
this.id = id;
//sprite_name
//atals
img.sprite = sp;
this.btn.onClick.AddListener(() => {
this.onClick(this.id);
});
}
// Update is called once per frame
void Update()
{
}
}
실행하면
1. 신규유저라면, (경로의 파일이 없으면) 슬롯이 5개 나오고 슬롯을 누르면
해당 하는 영웅이 생성된다. 영웅을 생성하고 영웅에 대한 정보를 json 파일인 hero_info.json이라는 이름으로 저장한다.
2. 기존유저라면, (경로의 파일이 있다면) 기존의 슬롯이 나오지 않고,
이미 영웅을 가지고 있으니, 버튼을 눌러 영웅을 로드하라는 버튼이 나오고 이 버튼을 누르면, 저장한 영웅이 로드 된다.
지금은 기존의 슬롯이 전부 사라지지만,
조금 고쳐서, 새로운 버튼이 나오는 것이 아닌,
저장하고 있는 영웅의 버튼만 제외하고, sprite를 자물쇠로 바꾸고, 버튼을 비활성화 시켜 동작하지 않는 방식으로
바꾸어 보려고 한다.
이 이후는 다음 포스트에서 이어서 하겠다.
'유니티 심화' 카테고리의 다른 글
유니티 GUI (0) | 2023.09.04 |
---|---|
Hero SHooter 개발일지 2 (0) | 2023.09.03 |
Hero Shooter 새로운 Input System 활용한 조이스틱 이동 (0) | 2023.09.01 |
Hero Shooter new Input System Test (0) | 2023.08.31 |
HeroShooter 개발일지1 (0) | 2023.08.30 |