[2025_10_16]Json-2

2025. 10. 16. 21:06TIL

게임 개발 중 아이템 저장/로드 시스템 구현 중 여러 문제를 마주쳤다.

1. 상속 구조에서의 List 저장 문제

초기 설계

csharp
public List<Item> playerInventory; //이렇게 하면 안됨
public List<Item> equipItem;
```

**문제점**
- `Item` 클래스를 상속받은 `Weapon`, `Armor`, `Potion` 클래스의 고유 속성이 저장되지 않음
- JSON 직렬화 시 부모 클래스(`Item`)의 속성만 저장됨
- `Weapon.atk`, `Armor.def`, `Potion.healAmount` 등이 무시됨

**직렬화/역직렬화 과정에서 발생하는 일**
[저장 시]
→ JSON은 List<Item>을 보고 Item 속성만 저장
→ 자식 클래스의 고유 속성 무시

[로드 시]
→ JSON은 new Item()으로 객체 생성
→ Weapon/Armor/Potion이 아닌 Item 객체로 복원

→ 타입 캐스팅 불가능
→ 자식 클래스 고유 기능 사용 불가
→ 게임 로직 깨짐!

 

해결 방법

csharp
// 타입별로 리스트 분리
public List<Weapon> weapons { get; set; }
public List<Armor> armors { get; set; }
public List<Potion> potions { get; set; }

2. 포션 로드 시 깨지는 문제

시도 1: Enum 직렬화 문제로 추정

 
 
csharp
// Enum을 문자열로 저장하도록 설정
Converters = { new JsonStringEnumConverter() }

→ 문자열로는 제대로 저장되지만 여전히 로드 실패

해결방안: 기본 생성자 추가

csharp
// 기본 생성자 없음
public Potion(int id, string name, string desc, int price, 
              float healAmount, ItemType type, PotionType _potionType) 
    : base(id, name, desc, price, type)
{
    this.healAmount = healAmount;
    this.potionType = _potionType;
}

// 기본 생성자 추가
public Potion() { } // 역직렬화를 위한 기본 생성자

의문점: Weapon이나 Armor에는 기본 생성자가 없는데 왜 정상 동작할까? -> 추가 조사 필요


3. 생성자 매개변수 이름 불일치 문제

문제의 핵심

 
csharp
public class Potion : Item
{
    public PotionType potionType { get; set; } // 속성명: potionType
    
    // 매개변수명이 속성명과 다름
    public Potion(int id, string name, string desc, int price, 
                  float healAmount, ItemType type, PotionType _potionType) 
        : base(id, name, desc, price, type)
    {
        this.healAmount = healAmount;
        this.potionType = _potionType; // 매개변수명: _potionType
    }
}

문제 원인

  • JSON 역직렬화 시 속성명(potionType)과 매개변수명(_potionType)이 달라서 매칭 실패
  • 생성자가 제대로 호출되지 않음

해결 방법

 
 
csharp
// 매개변수명을 속성명과 일치시킴
public Potion(int id, string name, string desc, int price, 
              float healAmount, ItemType type, PotionType potionType) // _ 제거
    : base(id, name, desc, price, type)
{
    this.healAmount = healAmount;
    this.potionType = potionType;
}

 

배운 점

  1. 상속 구조에서 JSON 직렬화 주의: 부모 타입으로 리스트를 만들면 자식의 고유 속성이 손실됨
  2. JSON 역직렬화는 기본 생성자나 속성명 매칭 필요: 생성자 매개변수명과 속성명이 일치해야 함
  3. 싱글턴 사용 시 항상 변수에 캐싱하기: 성능 최적화 (튜터님 피드백)
  4. JSON 직렬화 깊이 있게 공부 필요: 더 복잡한 상황 대비



+트러블 슈팅 
윈도우 11환경에서는 콘솔변경 불가능(사이즈 등)

 

원인: 윈도우 10에서 11로 버전 업그레이드와 함께 콘솔 실행창의 디폴트 값이(cmd->terminal)로 변경 됨

그로 인해 사용자가 직접 디폴트 셋팅을 변경하지 않는 이상 소스코드상의 범용적인 해결은 불가능함을 확인 함

 

해결->관리자 권한으로 IDE를 실행 후 콘솔 사이즈 조절하는 코드 삽입하여 해결하였습니다.

추후, 어플리케이션 실행시 필요 실행환경을 명시하는 UI추가 필요하다고 생각합니다.