我一直在使用保存系统来保存我的播放器数据,并且工作正常。但是,由于所有属性(健康状况等)都分为不同的类(例如PlayerHealthManager),因此我不确定什么是编译所有Players Data的最佳方法。现在,我很确定自己的操作方式完全是一团糟,而且在很多地方可能是错误的。
我有一个基本的Player类,该类使用Singleton,基本上持有对我需要其数据的所有组件的引用,例如PlayerHealthManager。然后,我有一个PlayerDataManager类,该类使用单例中的信息将Player数据编译为一个结构并将其发送到SaveSystem,但这确实很麻烦。代码附在下面。如果有人知道做事的更好方法,或者这是正确的,将不胜感激
public class PlayerDataManager : MonoBehaviour
{
public static event Action<PlayerData> OnPlayerDataLoaded = delegate { };
void Start()
{
PlayerData data = (PlayerData)SaveSystem.LoadPlayer();
OnPlayerDataLoaded(data);
}
void OnDisable()
{
SavePlayerData();
}
public PlayerData GetPlayerData()
{
if (Player.instance != null)
{
var playerData = new PlayerData();
Player p = Player.instance;
// Players Health Fields
playerData.health = p.HealthManager.Health;
playerData.maxHealth = p.HealthManager.MaxHealth;
// Player position fields
playerData.position = new float[2];
playerData.position[0] = p.transform.position.x;
playerData.position[1] = p.transform.position.y;
return playerData;
}
else
{
Debug.LogError("No player found");
return new PlayerData();
}
}
public void SavePlayerData()
{
SaveSystem.SavePlayer(GetPlayerData());
}
}
[RequireComponent(typeof(PlayerHealthManager))]
public class Player : MonoBehaviour
{
PlayerHealthManager healthManager;
public static Player instance = null;
public PlayerHealthManager HealthManager { get { return healthManager; } }
void Awake()
{
if (instance == null)
{
instance = this;
}
else
{
Destroy(gameObject);
}
}
void OnEnable()
{
healthManager = GetComponent<PlayerHealthManager>();
PlayerDataManager.OnPlayerDataLoaded += InitializeData;
}
void OnDisable()
{
PlayerDataManager.OnPlayerDataLoaded -= InitializeData;
}
void InitializeData(PlayerData data)
{
Vector2 newPosition = new Vector2(data.position[0], data.position[1]);
transform.position = newPosition;
healthManager.InitializeData(data);
}
}
答案 0 :(得分:1)
我相信您正在序列化SaveSystem
中的数据。使类/字段/属性可序列化(根据您使用的序列化器的不同,方法也不同),因此您不必将数据克隆到另一个对象。
基本上,您希望摆脱GetPlayerData
和PlayerData
并能够进行SaveSystem.SavePlayer(Player.instance);
Player类已经拥有所有信息,并且您可以决定应该序列化什么,而不必序列化什么。
如果您要将可序列化数据保留在单独的类/结构PlayerData
中,请在您的Player类中添加PlayerData playerdata;
,并在PlayerData类中添加PlayerHealthManager
和其他字段。然后,您可以做SaveSystem.SavePlayer(Player.instance.playerData);
如果是二进制序列化,我可以推荐协议缓冲区。它使序列化数据变得简单并且非常有效。您可以使用protobuf-net进行快速集成。