我有一个游戏,玩家拿起武器,然后将其作为 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;
}
但是我一直因为这样的设置而收到此错误:
SerializationException: Type UnityEngine.GameObject is not marked as Serializable.
我到底做错了什么?
经过几个小时的实验,我得出结论:Unity 无法用
GameObject
序列化 BinaryFormatter
。 Unity 在其 API 文档中声称这是可能的,但事实并非如此。
如果您想删除错误而不删除_weapon游戏对象,您应该替换...
[SerializeField]
private GameObject _weapon;
与
[NonSerialized]
private GameObject _weapon;
这将使其余代码运行而不会引发异常,但您不能
反序列化_weapon
游戏对象。您可以
反序列化其他字段。 或
您可以将 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;
}
如果你想说序列化变换,你可以通过创建一个新的 Vector3 位置、Vector3 比例、Vector4 四元数并将其序列化来解决这个问题,然后在反序列化时将此数据输入到新的变换中(例如)。
但是尝试序列化与网格渲染器关联的实际网格数据将证明是一项相当复杂的任务。更好的方法可能只是序列化一个 int 或代表网格 ID 的东西,然后在加载时将其转换为正确的引用。