Vector3 不可序列化 Unity3D

Vector3 not serializable Unity3D

好的,所以我遵循了 Unity3D 数据持久化教程,一切都很顺利,直到我尝试保存 Vector3 类型的数据。本教程仅展示如何保存 int 和 strings。

当我使用函数 Save() 时,控制台显示 says: "SerializationException: Type UnityEngine.Vector3 is not marked as Serializable.

但是正如您从我的代码中看到的那样,我将其包含在 Serializable 部分下。我正在尝试保存我的 playerPosition。谢谢

using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Collections.Generic;

public class GameManager : MonoBehaviour 
{
    public static GameManager control;

public float health;
public float mana;
public float experience;
public Vector3 playerPosition;
public List<Item> inventory = new List<Item>();

void Awake()
{
    if(control == null)
    {
        DontDestroyOnLoad(gameObject);
        control = this;
    }
    else if(control != this)
    {
        Destroy(gameObject);
    }
}

// Use this for initialization
void Start (){}

// Update is called once per frame
void Update () {}

void OnGUI() 
{
    GUI.Box(new Rect(10, 10, 100, 30), "Health: " + health);
    GUI.Box(new Rect(10, 30, 100, 30), "Mana: " + mana);
    GUI.Box(new Rect(10, 50, 100, 30), "Experience: " + experience);
}

public void SaveSlot1()
{
    BinaryFormatter bf = new BinaryFormatter();
    FileStream file = File.Create(Application.persistentDataPath + 
                                  "/saveData1.dat");

    PlayerData data = new PlayerData();
    data.health = health;
    data.mana = mana;
    data.experience = experience;
    data.playerPosition = playerPosition;

    for(int i = 0; i <inventory.Count; i++)
    {
        //data.inventory[i] = inventory[i];
    }

    bf.Serialize(file, data);
    file.Close();
}

public void LoadSlot1()
{
    if(File.Exists(Application.persistentDataPath +
                   "/saveData1.dat") )
    {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Open(Application.persistentDataPath + 
                                    "/saveData1.dat", FileMode.Open);
        PlayerData data = (PlayerData)bf.Deserialize(file);
        file.Close();

        health = data.health;
        mana = data.mana;
        experience = data.experience;
        playerPosition = data.playerPosition;

        for(int i = 0; i <inventory.Count; i++)
        {
            //inventory[i] = data.inventory[i];
        }
    }

}

[Serializable]
class PlayerData
{
    public float    health;
    public float    mana;
    public float    experience;
    public Vector3  playerPosition;
    public List<Item> inventory = new List<Item>();

    //position
    //spells
    //
}
}

将某些内容标记为可序列化只是让 .NET 知道您将要使用序列化。到那时,数据模型中的每个 属性 也必须是可序列化的,要么像 int 和字符串那样本质上是可序列化的,要么是一种也被标记为可序列化的类型。有几个选项

[Serializable]
class PlayerData
{
    public PlayerData()
    {
       playerPosition = Vector3.zero;
    }

    public float    health;
    public float    mana;
    public float    experience;
    [NonSerialized]
    public Vector3  playerPosition;

    public double playerPositionX
    { 
       get 
       {
         return playerPosition.x;
       }
       set
       {
         playerPosition.x = value;
       }
    }
    public double playerPositionY
    { 
       get 
       {
         return playerPosition.y;
       }
       set
       {
         playerPosition.y = value;
       }
    }

    public double playerPositionZ
    { 
       get 
       {
         return playerPosition.z;
       }
       set
       {
         playerPosition.z = value;
       }
    }

    public List<Item> inventory = new List<Item>();
}

第一个选项不会序列化矢量场,而是使用属性。有一个向量开始很重要。

另一种选择是在您的 class 上实现 ISerializable 接口,然后专门控制要写入的字段。该接口实现起来有些棘手,here is a MSDN link that explains some good and bad examples