如何在Unity中序列化和保存GameObject

Joe*_*eyL 3 c# unity-game-engine

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

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;
}
Run Code Online (Sandbox Code Playgroud)

但是我一直在设置此错误时遇到此错误:

SerializationException: Type UnityEngine.GameObject is not marked as Serializable.
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Pro*_*mer 11

AFTR实验小时,我来到了结论,即统一不能序列化GameObjectBinaryFormatter.Unity声称可以在他们的API文档中使用,但事实并非如此.

如果你想删除错误而不删除_weapon GameObject,你应该替换...

[SerializeField]
private GameObject _weapon;
Run Code Online (Sandbox Code Playgroud)

[NonSerialized]
private GameObject _weapon;
Run Code Online (Sandbox Code Playgroud)

这将使其余代码运行而不抛出异常,但您无法反序列化_weaponGameObject.您可以反序列化其他字段.

要么

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

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("\0", "")).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;
}
Run Code Online (Sandbox Code Playgroud)

  • *"经过几个小时的实验,我得出结论,Unity无法使用BinaryFormatter序列化GameObject.Unity声称可以在他们的API文档中使用,但事实并非如此."*我同意你100%. (2认同)