如何在 Unity 中序列化和保存游戏对象 [英] How to serialize and save a GameObject in Unity

查看:87
本文介绍了如何在 Unity 中序列化和保存游戏对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个游戏,玩家拿起武器,然后将它作为 GameObject 变量放置到我的名为MainHandWeapon"的玩家中,我试图通过场景更改来保存该武器,因此我试图保存它.我的处理方式如下:

I have a game where the player picks up a weapon and it is then placed as the GameObject variable to my player called "MainHandWeapon" and I am trying to save that weapon through scene changes so I am trying to save it. How I handle this is as follows :

public class Player_Manager : Character, Can_Take_Damage {

    // The weapon the player has.
    public GameObject MainHandWeapon;

    public void Save()
    {
        // Create the Binary Formatter.
        BinaryFormatter bf = new BinaryFormatter();
        // Stream the file with a File Stream. (Note that File.Create() 'Creates' or 'Overwrites' a file.)
        FileStream file = File.Create(Application.persistentDataPath + "/PlayerData.dat");
        // Create a new Player_Data.
        Player_Data data = new Player_Data ();
        // Save the data.
        data.weapon = MainHandWeapon;
        data.baseDamage = BaseDamage;
        data.baseHealth = BaseHealth;
        data.currentHealth = CurrentHealth;
        data.baseMana = BaseMana;
        data.currentMana = CurrentMana;
        data.baseMoveSpeed = BaseMoveSpeed;
        // Serialize the file so the contents cannot be manipulated.
        bf.Serialize(file, data);
        // Close the file to prevent any corruptions
        file.Close();
    }
}

[Serializable]
class Player_Data
{
    [SerializeField]
    private GameObject _weapon;
    public GameObject weapon{
        get { return _weapon; }
        set { _weapon = value; }
    }

    public float baseDamage;
    public float baseHealth;
    public float currentHealth;
    public float baseMana;
    public float currentMana;
    public float baseMoveSpeed;
}

但我不断收到此设置的错误:

But I keep getting this error from having this setup :

SerializationException: Type UnityEngine.GameObject is not marked as Serializable.

我到底做错了什么?

推荐答案

经过数小时的实验,我得出的结论是 Unity 无法 使用 BinaryFormatter 序列化 GameObject.Unity 在他们的 API 文档中声称这是可能的,但它不可能.

Aftr hours of experiment, I came to conclusion that Unity cannot serialize GameObject with BinaryFormatter. Unity claims that is possible in their API documentation but it's not.

如果你想在不移除_weapon GameObject的情况下移除错误,你应该替换...

If you want to remove the error without removing the _weapon GameObject, you should replace ...

[SerializeField]
private GameObject _weapon;

[NonSerialized]
private GameObject _weapon;

这将使您的其余代码运行而不会引发异常,但您不能反序列化 _weapon 游戏对象.您可以反序列化其他字段.

This will let the rest of your code run without throwing exception, but you can't deserialize _weapon GameObject. You can deserialize other fields.

您可以将 GameObject 序列化为 xml.这可以毫无问题地序列化 GameObject.它以人类可读的格式保存数据.如果您关心安全性或不希望玩家在自己的设备上修改分数,您可以加密,转换成保存之前的>二进制或Base-64格式强>它到磁盘.

You can serialize GameObject as xml. This can serialize GameObject without any problem. It saves the data in human readable format. If you care about security or don't want players modifying scores on their own devices, you can encrypt, convert it into binary or Base-64 format before saving it to the disk.

using UnityEngine;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;
using System.Runtime.Serialization;
using System.Xml.Linq;
using System.Text;

public class Player_Manager : MonoBehaviour
{

    // The weapon the player has.
    public GameObject MainHandWeapon;

    void Start()
    {
        Save();
    }

    public void Save()
    {
        float test = 50;

        Debug.Log(Application.persistentDataPath);

        // Stream the file with a File Stream. (Note that File.Create() 'Creates' or 'Overwrites' a file.)
        FileStream file = File.Create(Application.persistentDataPath + "/PlayerData.dat");
        // Create a new Player_Data.
        Player_Data data = new Player_Data();
        //Save the data.
        data.weapon = MainHandWeapon;
        data.baseDamage = test;
        data.baseHealth = test;
        data.currentHealth = test;
        data.baseMana = test;
        data.currentMana = test;
        data.baseMoveSpeed = test;

        //Serialize to xml
        DataContractSerializer bf = new DataContractSerializer(data.GetType());
        MemoryStream streamer = new MemoryStream();

        //Serialize the file
        bf.WriteObject(streamer, data);
        streamer.Seek(0, SeekOrigin.Begin);

        //Save to disk
        file.Write(streamer.GetBuffer(), 0, streamer.GetBuffer().Length);

        // Close the file to prevent any corruptions
        file.Close();

        string result = XElement.Parse(Encoding.ASCII.GetString(streamer.GetBuffer()).Replace("", "")).ToString();
        Debug.Log("Serialized Result: " + result);

    }
}


[DataContract]
class Player_Data
{
    [DataMember]
    private GameObject _weapon;

    public GameObject weapon
    {
        get { return _weapon; }
        set { _weapon = value; }
    }

    [DataMember]
    public float baseDamage;
    [DataMember]
    public float baseHealth;
    [DataMember]
    public float currentHealth;
    [DataMember]
    public float baseMana;
    [DataMember]
    public float currentMana;
    [DataMember]
    public float baseMoveSpeed;
}

这篇关于如何在 Unity 中序列化和保存游戏对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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