20240925 / Unity_6차 2주차 수요일
내가 어제 무슨 말을 했더라...
정확히 남은 작업의 1,2,3번을 했고 (저장 및 불러오기, 상점, 여관) 나머지는 그대로 손도 못대고 끝.
생각보다 저장 기능이 쉽지 않았다.
예전에 xml을 써봤던지라 이번에는 json을 써봤는데 시간도 없는거 그냥 익숙한 xml을 쓸 걸 그랬다.
하지만 사실 나를 고생하게 만든 원인은 json이 아니었다.
바로 언제든 저장하고 불러와야 할 데이터가 저장하기 너무 안좋은 구조를 하고 있기에 그랬다.
아이템 데이터는 인스턴스를 그때그때 만들지 않고
프로그램 실행 시부터 정적 데이터로 만들어 쓰고 싶었다.
그렇게 스태틱 인스턴스로 된 모든 아이템을 사용자가 구매하거나 상점에 진열될 때에는
스태틱 데이터를 월드 데이터로 전환해서 인벤토리에 참조했다.
class WorldItemPotion
{
public ItemPotion itemPotion { get; }
public int num { get; set; }
public WorldItemPotion(ItemPotion _itemPotion, int _num)
{
itemPotion = _itemPotion;
num = _num;
}
}
class ItemPotion
{
public string name { get; } //이름은 식별자의 역할을 하기 때문에 중복되면 안됨
public string information { get; }
public ITP type { get; }
public int power { get; }
public int value { get; }
public ItemPotion(string _name, string _information, ITP _type, int _power, int _value)
{
name = _name;
information = _information;
type = _type;
power = _power;
value = _value;
}
}
WorldItemPotion.itemPotion 이 외부의 static ItemPotion 인스턴스를 참조하는 식
인벤토리는 List<WorldItemPotion> 필드로 구현했다.
ItemPotion 내에 수량 변수를 추가하고 인벤토리를 List<ItemPotion> 으로 만들면 쉬운데
뭔가 ItemPotion 의 필드를 전부 읽기 전용으로 만들고 싶다는 이상한 고집이 있었다...
위와 같이 해도 저장을 생각하지 않고 개발할 때에는 잘만 돌아갔다.
오히려 아이템 인스턴스는 읽기만 한다고 못박아두니 정적 데이터 필드가 더 깔끔해 보였다.
그런데 머리를 싸매고 생각해 봐도 List<WorldItemPotion> 를 저장할 방법이 떠오르지 않았다.
이건 xml을 써도 똑같을 것이다.
결국 Dictionay<string, int> 필드를 만들어 저장할 아이템 이름과 수량만 쓰고
불러올 때는 이름이랑 일치하는 아이템을 인벤토리에 넣어주는 식으로 해결했다.
dic_inventoryPotion = new Dictionary<string, int>();
foreach (WorldItemPotion i in inventoryPotion) dic_inventoryPotion.Add(i.itemPotion.name, i.num);
dic_inventoryGear = new Dictionary<string, bool>();
foreach (WorldItemGear i in inventoryGear) dic_inventoryGear.Add(i.itemGear.name, i.equipped);
dic_equippedGear = new Dictionary<string, int>();
for (int i = 0; i < (int)GST.MAX; i++)
{
if (equippedGear[i] != null) dic_equippedGear.Add(equippedGear[i].name, i);
}
dic_gearShop = new Dictionary<string, int>();
foreach (ItemGear i in gearShop.list) dic_gearShop.Add(i.name, 0);
데이터 저장할 때.
if (playerData.dic_inventoryPotion != null)
{
foreach (KeyValuePair<string, int> pair in playerData.dic_inventoryPotion)
{
ItemPotion ip = Program.globalItemData.potions.Find(i => i.name == pair.Key);
if (ip != null) playerData.inventoryPotion.Add(new WorldItemPotion(ip, pair.Value));
}
}
if (playerData.dic_inventoryGear != null)
{
foreach (KeyValuePair<string, bool> pair in playerData.dic_inventoryGear)
{
ItemGear ig = Program.globalItemData.gears.Find(i => i.name == pair.Key);
if (ig != null) playerData.inventoryGear.Add(new WorldItemGear(ig, pair.Value));
}
}
if (playerData.dic_equippedGear != null)
{
foreach (KeyValuePair<string, int> pair in playerData.dic_equippedGear)
{
playerData.EquipGear(pair.Key, (GST)pair.Value);
}
}
if (playerData.dic_gearShop != null)
{
foreach (KeyValuePair<string, int> pair in playerData.dic_gearShop)
{
ItemGear ig = Program.globalItemData.gears.Find(i => i.name == pair.Key);
if (ig != null) playerData.gearShop.list.Add(ig);
}
}
데이터 불러올 때
당장은 동작한다지만 만약 모든 기능을 구현했다면 List가 한가득 나올 텐데,
일일이 저렇게 해줘야 하는 건가?
이게 이렇게 어려울 일인가?
하여튼 과제 제출은 끝났다.
되돌아보면 UI 구상하는데 반 이상의 시간을 쓴 것 같다.
대단한 로직이 들어있는 것도 아니니 버그가 UI에서만 일어나는 것도 당연하지만.
아무튼 이제 팀프로젝트나 신경써야지~