如何在 Unity 中序列化和保存游戏对象 [英] How to serialize and save a GameObject in 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屋!