런타임시 게임 저장 데이터 불러오기 및 저장 기능
JsonController.cs
using UnityEngine;
using System.IO;
using System.Text;
public class JsonController
{
public UserDB LoadUserData(string path)
{
if (File.Exists(Application.persistentDataPath + path))
{
string json = File.ReadAllText(Application.persistentDataPath + path);
Debug.Log("UserData loded to: " + path);
return JsonUtility.FromJson<UserDB>(json);
}
Debug.LogWarning("UserData file not found!");
return null;
}
public void SaveUserData(UserDB saveData, string path)
{
string jsonUserData = JsonUtility.ToJson(saveData, true);
FileStream fileStream = new FileStream(Application.persistentDataPath + path, FileMode.Create);
byte[] data = Encoding.UTF8.GetBytes(jsonUserData);
fileStream.Write(data, 0, data.Length);
fileStream.Close();
//File.WriteAllText(path, jsonUserData);
Debug.Log("UserData saved to: " + Application.persistentDataPath + path);
}
}
Application.persistentDataPath 메서드를 사용해야 PC,안드로이드에 빌드 했을대도 해당 경로로 이동해 데이터를 읽기/쓰기가 가능하기 때문에 해당 기능을 사용하였고 추가로 + path 기능은 "/userdata.json" 접근할 파일 경로를 적어주어 사용하면 된다.
Player.cs
public void Initialize()
{
//Model(UserData) 세팅
if (DataManager.Instance.LoadUserData() == null)
{
//새로하기 , 기본 능력치를 제공
userData = new UserData(DataManager.Instance.UserDB.GetByKey(TestID));
DataManager.Instance.SaveUserData(userData);
}
else
{
//이어하기
userData = new UserData(DataManager.Instance.LoadUserData());
}
}
Player는 DataManager의 접근해서 저장데이터가 있을경우 해당 json을 불러 데이터를 파싱하여 userData로 변환하여 사용하고 없는경우 UserDB에 있는 기본 User값을 호출하여 새로 생성하게 설계하였다.
Player,Enemy FSM 구조 설계
Player와 Enemy가 공통으로 사용하게 될 구조가 필요하기 때문에
팀원과 회의하여 BaseCharacter 및 BaseState ,Istate를 만들어서 사용하였고
각 State에서 사용하는 객체를 역참조하여 접근 할 수 있게 사용 하였다.
BaseCharacter.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class BaseCharacter : MonoBehaviour, ITakeDamageAble
{
protected StatHandler statHandler; //스텟 관리 클래스
//자식클래스들에 FSM 구조를 구현하였다.
public virtual void TakeDamage(float damage)
{
}
public virtual void TakeKnockBack(Vector3 direction, float force)
{
}
}
Player와 Enemy의 부모클래스로 추상클래스로 사용하여 구현 하였고 , Interface ITakeDamageAble을 사용하여 데미지 적용 기능은 필수이기에 Interface로 하였다.
Player와 Enemy는 퍼사드 + MVC 패턴을 사용하여 구현하기로 회의하였고
Mdoel : Player 의 UserData , Enemy의 EnemyDB 데이터
View : Player,Enemy의 AnimationController Class
Controller : Player,Enemy FSM 로직을 구현 및 기타 로직 설계
로 구조를 잡고 진행 하였다.
Istate.cs & BaseStateMachine.cs
public interface IState
{
void Enter();
void Exit();
void Update();
void FixedUpdate();
}
public class BaseStateMachine
{
protected IState currentState;
public void ChangeState(IState newState)
{
currentState?.Exit();
currentState = newState;
currentState?.Enter();
}
public void Update()
{
currentState?.Update();
}
public void FixedUpdateState()
{
currentState?.FixedUpdate();
}
}
FSM 구조는 해당 부모 클래스를 상속해서 다형성을 확보했습니다.