Обработка сбора данных игрока из нескольких скриптов [Unity] - PullRequest
0 голосов
/ 24 апреля 2019

Я работал над системой сохранения, чтобы сохранить данные моих игроков, и это работает нормально.Однако я не уверен, каков наилучший способ собрать все мои данные игроков, так как все их атрибуты (здоровье и т. Д.) Разделены на разные классы, например PlayerHealthManager.Прямо сейчас я почти уверен, что то, как я это делаю, - полный беспорядок, и, вероятно, во многих местах это неправильно.

У меня есть базовый класс 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);
    }
}

1 Ответ

1 голос
/ 24 апреля 2019

Я полагаю, что вы сериализуете данные в вашем SaveSystem. Сделайте классы / поля / атрибуты сериализуемыми (способы сделать это различаются в зависимости от используемого сериализатора), чтобы вам не приходилось клонировать данные в другой объект.

В основном вы хотите избавиться от GetPlayerData и PlayerData и уметь делать SaveSystem.SavePlayer(Player.instance); В классе игрока уже есть вся информация, и вы можете решить, что следует сериализовать, а что нет.

Если вы хотите сохранить данные serialazble в отдельном классе / struct PlayerData, добавьте PlayerData playerdata; к вашему классу Player и добавьте PlayerHealthManager и другие поля к классу PlayerData. Вы могли бы тогда сделать SaveSystem.SavePlayer(Player.instance.playerData);

В случае двоичной сериализации я могу порекомендовать протокольные буферы. Это делает сериализацию данных простой и очень эффективной. Вы можете использовать protobuf-net для быстрой интеграции.

...