본문 바로가기
스파르타 내배캠

스파르타 내배캠 Unity 3기 17일차

by LemongO 2024. 1. 16.

발표준비는 어려워

 

 

 

어제 세이브로드 구현 후 플레이어의 직업이 정상 출력되지 않는 버그가 있었다.

그 부분을 알아보자.

 


부모 타입의 객체를 자식 타입으로 관리하기는 힘들다.

 

왜 위 같은 타이틀을 썻는가...

플레이어를 저장시에 Warrior 로 생성된 객체라도 Player 로 저장되기 때문이다.

그리고 Player 타입으로 생성 되면 문제가 되는점이 다음과 같다.

 

public virtual string GetClassName() { return "잘못된 접근"; }
public override string GetClassName() { return "전사"; }

 

해당 코드는 상태창에서 플레이어의 직업 이름을 가져올 때 쓰이는 코드인데

Warrior 객체는 "전사" 로 출력이 되는데 Load 시에 Player 타입으로 생성되기 때문에 "잘못된 접근"으로 출력된다.

 

하지만 다행히

Save 시 T 타입으로 저장되고

Load 시 T 타입으로 불러와지게 설계를 했다.

 

그렇기 때문에 플레이어를 저장할 땐 Warrior로 생성된 플레이어라면 Warrior로 저장하면 된다!

 

라고 생각했다.

 

하지만 Dungeon 클래스 내부에서 사용되는 player 전역변수는 Player 타입으로 선언 되어있다.

// 인게임에서 사용될 Player
private Player player = null;

 

그렇다면 저장할 때는 반드시 Player로 저장이 된다는 것이다...

(사실 반드시란 없다. 캐스팅 하기 귀찮고 코드가 길어지니까 안 할 뿐이다.)

 

아무튼 Player 타입으로 저장된 플레이어를 직업에 맞게 로드하려면 어떻게 해야할까?

 

내가 해결한 방법은 Player 클래스에 enum 변수인 PlayerClass를 이용하는 것이다.

public PlayerClass MyClass          { get; private set; }

 

Player 클래스엔 PlayerClass 라는 enum 타입이 있고 캐릭터를 처음 생성시엔 직업이 MyClass 프로퍼티에 할당된다.

 

그러므로 Load 시에만 이 정보를 이용해 캐릭터를 그에 맞는 타입으로 생성하면 된다.

 

if (LoadGame<Player>("PlayerData.json") != null)
{
    switch (LoadGame<Player>("PlayerData.json").MyClass)
    {
        case PlayerClass.Warrior:
            player = LoadGame<Warrior>("PlayerData.json");
            break;
        case PlayerClass.Archer:
            player = LoadGame<Archer>("PlayerData.json");
            break;
        case PlayerClass.Magic:
            player = LoadGame<Magic>("PlayerData.json");
            break;
        case PlayerClass.Thief:
            player = LoadGame<Thief>("PlayerData.json");
            break;
        case PlayerClass.Deadbeat:
            player = LoadGame<Deadbeat>("PlayerData.json");
            break;
    }
}

 

이렇게 하면 정상적으로 불러오기가 가능하다.

정상적으로 Warrior 타입의 플레이어가 Load 되었다.