카테고리 없음

내일배움캠프 10일차 TIL 개인과제 마감

joseph2518 2024. 9. 25. 22:05

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에서만 일어나는 것도 당연하지만.

 

 

아무튼 이제 팀프로젝트나 신경써야지~