Vector3不可序列化的Unity3D

时间:2015-01-13 22:45:14

标签: unity3d

好的,所以我按照Unity3D数据持久性教程,一切顺利,直到我尝试保存Vector3类型的数据。本教程仅显示如何保存int和字符串。

当我使用Save()函数时,控制台告诉我"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
    //
}
}

1 个答案:

答案 0 :(得分:3)

将某些内容标记为Serializable只是让.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>();
}

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

另一种选择是在类上实现ISerializable接口,然后专门控制正在写入的字段。实现界面有点棘手,here is a MSDN link that explains some good and bad examples