UI슬롯에 버튼을 할당하여 UI슬롯을 클릭하면 영웅을 생성하도록 스크립트를 작성했다. 이때 UI슬롯에 for문을 돌려서 이벤트를 할당하는 식으로 코드를 짰는데 에러가 나서 검색해본 결과 클로저 문제인걸 알게됐다. 지역변수를 추가로 선언해서 문제를 해결했다. 클로저에 대해선 추가로 공부가 필요할 것 같다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using UnityEngine.U2D;
using Newtonsoft.Json;
public class App : MonoBehaviour
{
//프리펩이 저장될 변수
private List<GameObject> prefabs = new List<GameObject>();
private List<GameObject> fieldPrefabs = new List<GameObject> ();
[SerializeField]
private Image[] thumb;
[SerializeField]
private Button[] slots;
[SerializeField]
private SpriteAtlas atlas;
private Hero hero = null;
void Start()
{
//데이터 로드
DataManager.instance.LoadHeroData();
//프리펩 리소스 로드
this.LoadPrefabs();
this.UnlockHero();
for(int i=0; i<slots.Length; i++)
{
int heroId = i + 100;
slots[i].onClick.AddListener(() =>
{
if(hero == null)
{
this.CreateHero(heroId);
}
else
{
Debug.Log("이미 생성된 영웅이 있습니다.");
}
});
}
}
private void LoadPrefabs()
{
List<string> heroPrefabNames = DataManager.instance.GetHeroPrefabNames();
foreach (string prefabName in heroPrefabNames)
{
string path = string.Format("Prefab/{0}", prefabName);
GameObject prefab = Resources.Load<GameObject>(path);
this.prefabs.Add(prefab);
}
}
public void CreateHero(int id)
{
Debug.Log(Application.persistentDataPath);
string filePath = string.Format("{0}/Hero_Info", Application.persistentDataPath);
HeroInfo heroInfo = null;
if (File.Exists(filePath))
{
Debug.Log("기존 유저입니다.");
string json = File.ReadAllText(filePath);
Debug.Log(json);
heroInfo = JsonConvert.DeserializeObject<HeroInfo>(json);
}
else
{
Debug.Log("신규 유저입니다.");
HeroData herodata = DataManager.instance.GetHeroData(id);
heroInfo = new HeroInfo(herodata.id, herodata.max_hp, herodata.damage);
}
GameObject go = new GameObject();
go.name = "Hero";
Debug.Log(id - 100);
GameObject model = Instantiate(prefabs[id-100],go.transform);
hero = model.AddComponent<Hero>();
hero.Init(heroInfo, model);
SaveInfo();
}
private void SaveInfo()
{
string filePath = string.Format("{0}/Hero_Info", Application.persistentDataPath);
var json = JsonConvert.SerializeObject(hero.info);
File.WriteAllText(filePath,json);
}
private void UnlockHero()
{
for (int i = 0; i < thumb.Length; i++)
{
string spriteName = DataManager.instance.GetHeroSpriteName(i + 100);
this.thumb[i].sprite = this.atlas.GetSprite(spriteName);
}
}
}
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DataManager
{
public static readonly DataManager instance = new DataManager();
private Dictionary<int, HeroData> dicHeroDatas = new Dictionary<int, HeroData>();
private DataManager() { }
public void LoadHeroData()
{
TextAsset asset = Resources.Load<TextAsset>("Data/Hero_Data");
Debug.Log(asset);
HeroData[] heroDatas = JsonConvert.DeserializeObject<HeroData[]>(asset.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.dicHeroDatas.Add(data.id, data);
}
Debug.LogFormat("HeroData 로드 완료 : {0}", this.dicHeroDatas.Count);
}
public List<string> GetHeroPrefabNames()
{
List<string> list = new List<string>();
foreach(HeroData data in this.dicHeroDatas.Values)
{
list.Add(data.prefab_name);
}
return list;
}
public HeroData GetHeroData(int id)
{
return this.dicHeroDatas[id];
}
public string GetHeroSpriteName(int id)
{
return dicHeroDatas[id].sprite_name;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeroData
{
//id name max_hp damage prefab_name sprite_name
//int string float float string string
public int id;
public string name;
public float max_hp;
public float damage;
public string prefab_name;
public string sprite_name;
}
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;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Hero : MonoBehaviour
{
public HeroInfo info;
public GameObject model;
public void Init(HeroInfo info, GameObject model)
{
this.info = info;
this.model = model;
}
}
'유니티 심화' 카테고리의 다른 글
[UI] 스테이지 페이지 만들기 (0) | 2023.09.06 |
---|---|
[UI] 로그인 창 만들기 (0) | 2023.09.05 |
(수정중) 유니티 New Input System 사용하여 이동 구현 (0) | 2023.09.01 |
유니티 new Input System으로 조이스틱 사용하기 (0) | 2023.08.31 |
가장 가까운 무기 장비하기 + 배럴 공격하기 (0) | 2023.08.21 |