Vector3 不可序列化 Unity3D [英] Vector3 not serializable Unity3D

查看:82
本文介绍了Vector3 不可序列化 Unity3D的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Ok so I followed the Unity3D data persistence tutorial, everything is going smoothly until I tried to save a Vector3 type of data. The tutorial only shows how to save int and strings.

当我使用函数 Save() 时,控制台告诉我:"SerializationException:Type UnityEngine.Vector3 未标记为可序列化.

When I used the function Save() , the consoles shows me that says: "SerializationException: Type UnityEngine.Vector3 is not marked as Serializable.

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

But as you can see from my code, I included it under the Serializable part. I am trying to save my playerPosition. Thanks

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 和字符串一样固有地可序列化,或者是也标记为可序列化的类型.有几个选择

Marking something as Serializable just let's .NET to know that you are going to be using serialization. At that point every property all the way down the data model must also be serializable, either by being inherently serializable like ints and strings, or being a type that is also marked as serializable. There's a couple of options

[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>();
}

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

This first option will not serialize the vector field, and instead use the properties. Having a vector to start with is important.

另一种选择是在您的类上实现 ISerializable 接口,然后专门控制正在写入的字段.该接口实现起来有些棘手,这里是一个 MSDN 链接,解释了一些好的和不好的例子

The other option is to implement the ISerializable interface on your class and then specifically control what fields are being written. The interface is somewhat tricky to implement, here is a MSDN link that explains some good and bad examples

这篇关于Vector3 不可序列化 Unity3D的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆