保存和加载游戏数据不起作用
Saving and Loading Game Data Not Working
不确定为什么我的代码无法正常工作,因为我遵循了我发现的示例。尝试让我的 iOS 游戏使用 Unity3D 保存和加载数据,但不使用 player.prefs.
现场我有这个
void OnDisable(){
GameController.Save ();
}
void OnEable(){
GameController.Load ();
}
游戏控制器是一个静态方法..
static public void Save()
{
Debug.Log("Saving Player Data...");
print ("Saving Player Data...");
var bf = new BinaryFormatter();
var file = File.Create(Application.persistentDataPath + "/CatEscapeInfo.dat");
var data = new PlayerData
{
PlayerLives = PlayerLives,
Score = Score,
Distance = Distance,
CurrentLevelNo = CurrentLevelNo,
HighestLevelCompleted = HighestLevelCompleted
};
bf.Serialize(file, data);
file.Close();
//PlayerPrefs.SetString (data);
Debug.Log ("Player Data Saved: " + PlayerLives + ", " + Score);
print ("Player Data Saved: " + PlayerLives + ", " + Score);
}
static public void Load()
{
Debug.Log("Loading Player Data...");
if (File.Exists(Application.persistentDataPath + "/CatEscapeInfo.dat"))
{
var bf = new BinaryFormatter();
var file = File.Open(Application.persistentDataPath + "/CatEscapeInfo.dat", FileMode.Open);
var data = bf.Deserialize(file) as PlayerData;
file.Close();
Debug.Log("Player Data Loaded: " + data.PlayerLives + ", " + data.Score);
print ("Player Data Loaded: " + data.PlayerLives + ", " + data.Score);
if (data != null)
{
PlayerLives = data.PlayerLives;
Score = data.Score;
Distance = data.Distance;
CurrentLevelNo = data.CurrentLevelNo;
HighestLevelCompleted = data.HighestLevelCompleted;
}
}
}
即使我运行了这段代码,当我在 iOS 上手动关闭游戏并重新启动时,它也永远不会将游戏加载回原来的状态。
有什么想法吗?我错过了什么吗?
更新:
在 iOS XCode 中,我发现它在尝试 "Load" 时吐出了这个堆栈跟踪,尽管此时文件还不存在。
加载时这是堆栈跟踪:
> (Filename:
> /Applications/buildAgent/work/d63dfc6385190b60/artifacts/iPhonePlayer-armv7Generated/UnityEngineDebug.cpp
> Line: 49)
>
> SerializationException: Unexpected binary element: 255 at
> System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject
> (BinaryElement element, System.IO.BinaryReader reader, System.Int64&
> objectId, System.Object& value,
> System.Runtime.Serialization.SerializationInfo& info) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject
> (BinaryElement element, System.IO.BinaryReader reader) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph
> (BinaryElement elem, System.IO.BinaryReader reader, Boolean
> readHeaders, System.Object& result,
> System.Runtime.Remoting.Messaging.Header[]& headers) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize
> (System.IO.Stream serializationStream,
> System.Runtime.Remoting.Messaging.HeaderHandler handler) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize
> (System.IO.Stream serializationStream) [0x00000] in <filename
> unknown>:0 at GameController.Load () [0x00000] in <filename
> unknown>:0 at GameController.OnEnable () [0x00000] in <filename
> unknown>:0 (Filename: Line: -1)
保存时,这是堆栈跟踪:
> Saving Player Data... UnityEngine.Debug:Internal_Log(Int32, String,
> Object) UnityEngine.Debug:Log(Object)
> UnityEngine.MonoBehaviour:print(Object) GameController:Save()
> GameController:OnDisable() UnityEngine.Object:Destroy(Object, Single)
> UnityEngine.Object:Destroy(Object) GameController:Awake() (Filename:
> /Applications/buildAgent/work/d63dfc6385190b60/artifacts/iPhonePlayer-armv7Generated/UnityEngineDebug.cpp
> Line: 49)
>
> ExecutionEngineException: Attempting to JIT compile method
> 'PlayerData__TypeMetadata4:.ctor ()' while running with --aot-only.
>
> at System.Reflection.MonoCMethod.Invoke (System.Object obj,
> BindingFlags invokeAttr, System.Reflection.Binder binder,
> System.Object[] parameters, System.Globalization.CultureInfo culture)
> [0x00000] in <filename unknown>:0 Rethrow as
> TargetInvocationException: Exception has been thrown by the target of
> an invocation. at System.Reflection.MonoCMethod.Invoke
> (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder
> binder, System.Object[] parameters, System.Globalization.CultureInfo
> culture) [0x00000] in <filename unknown>:0 at
> System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr,
> System.Reflection.Binder binder, System.Object[] parameters,
> System.Globalization.CultureInfo culture) [0x00000] in <filename
> unknown>:0 at System.Reflection.ConstructorInfo.Invoke
> (System.Object[] parameters) [0x00000] in <filename unknown>:0 at
> System.Activator.CreateInstance (System.Type type, Boolean nonPublic)
> [0x00000] in <filename unknown>:0 at
> System.Activator.CreateInstance (System.Type type) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.CreateMemberTypeMetadata
> (System.Type type) [0x00000] in <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.GetObjectData
> (System.Object obj,
> System.Runtime.Serialization.Formatters.Binary.TypeMetadata& metadata,
> System.Object& data) [0x00000] in <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObject
> (System.IO.BinaryWriter writer, Int64 id, System.Object obj) [0x00000]
> in <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectInstance
> (System.IO.BinaryWriter writer, System.Object obj, Boolean
> isValueObject) [0x00000] in <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteQueuedObjects
> (System.IO.BinaryWriter writer) [0x00000] in <filename unknown>:0
> at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectGraph
> (System.IO.BinaryWriter writer, System.Object obj,
> System.Runtime.Remoting.Messaging.Header[] headers) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize
> (System.IO.Stream serializationStream, System.Object graph,
> System.Runtime.Remoting.Messaging.Header[] headers) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize
> (System.IO.Stream serializationStream, System.Object graph) [0x00000]
> in <filename unknown>:0 at GameController.Save () [0x00000] in
> <filename unknown>:0 at GameController.OnDisable () [0x00000] in
> <filename unknown>:0 UnityEngine.Object:Destroy(Object, Single)
> UnityEngine.Object:Destroy(Object) GameController:Awake()
将此代码放入场景脚本中的 Awake
或 Start
函数:
// Forces a different code path in the BinaryFormatter that doesn't rely on run-time code generation (which would break on iOS).
Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
默认情况下,Mono 二进制序列化程序使用 iOS 不支持的 JIT 编译。幸运的是,有一种方法(上面的代码)可以将其切换为使用反射。
证明/另见:
Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
在 Unity 编辑器中创建错误,例如:
"Environment" not found in namespace
经过数小时的搜索,我发现以下代码可以完美运行:
System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER","yes");
希望对您有所帮助。
不确定为什么我的代码无法正常工作,因为我遵循了我发现的示例。尝试让我的 iOS 游戏使用 Unity3D 保存和加载数据,但不使用 player.prefs.
现场我有这个
void OnDisable(){
GameController.Save ();
}
void OnEable(){
GameController.Load ();
}
游戏控制器是一个静态方法..
static public void Save()
{
Debug.Log("Saving Player Data...");
print ("Saving Player Data...");
var bf = new BinaryFormatter();
var file = File.Create(Application.persistentDataPath + "/CatEscapeInfo.dat");
var data = new PlayerData
{
PlayerLives = PlayerLives,
Score = Score,
Distance = Distance,
CurrentLevelNo = CurrentLevelNo,
HighestLevelCompleted = HighestLevelCompleted
};
bf.Serialize(file, data);
file.Close();
//PlayerPrefs.SetString (data);
Debug.Log ("Player Data Saved: " + PlayerLives + ", " + Score);
print ("Player Data Saved: " + PlayerLives + ", " + Score);
}
static public void Load()
{
Debug.Log("Loading Player Data...");
if (File.Exists(Application.persistentDataPath + "/CatEscapeInfo.dat"))
{
var bf = new BinaryFormatter();
var file = File.Open(Application.persistentDataPath + "/CatEscapeInfo.dat", FileMode.Open);
var data = bf.Deserialize(file) as PlayerData;
file.Close();
Debug.Log("Player Data Loaded: " + data.PlayerLives + ", " + data.Score);
print ("Player Data Loaded: " + data.PlayerLives + ", " + data.Score);
if (data != null)
{
PlayerLives = data.PlayerLives;
Score = data.Score;
Distance = data.Distance;
CurrentLevelNo = data.CurrentLevelNo;
HighestLevelCompleted = data.HighestLevelCompleted;
}
}
}
即使我运行了这段代码,当我在 iOS 上手动关闭游戏并重新启动时,它也永远不会将游戏加载回原来的状态。 有什么想法吗?我错过了什么吗?
更新: 在 iOS XCode 中,我发现它在尝试 "Load" 时吐出了这个堆栈跟踪,尽管此时文件还不存在。
加载时这是堆栈跟踪:
> (Filename:
> /Applications/buildAgent/work/d63dfc6385190b60/artifacts/iPhonePlayer-armv7Generated/UnityEngineDebug.cpp
> Line: 49)
>
> SerializationException: Unexpected binary element: 255 at
> System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject
> (BinaryElement element, System.IO.BinaryReader reader, System.Int64&
> objectId, System.Object& value,
> System.Runtime.Serialization.SerializationInfo& info) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject
> (BinaryElement element, System.IO.BinaryReader reader) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph
> (BinaryElement elem, System.IO.BinaryReader reader, Boolean
> readHeaders, System.Object& result,
> System.Runtime.Remoting.Messaging.Header[]& headers) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize
> (System.IO.Stream serializationStream,
> System.Runtime.Remoting.Messaging.HeaderHandler handler) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize
> (System.IO.Stream serializationStream) [0x00000] in <filename
> unknown>:0 at GameController.Load () [0x00000] in <filename
> unknown>:0 at GameController.OnEnable () [0x00000] in <filename
> unknown>:0 (Filename: Line: -1)
保存时,这是堆栈跟踪:
> Saving Player Data... UnityEngine.Debug:Internal_Log(Int32, String,
> Object) UnityEngine.Debug:Log(Object)
> UnityEngine.MonoBehaviour:print(Object) GameController:Save()
> GameController:OnDisable() UnityEngine.Object:Destroy(Object, Single)
> UnityEngine.Object:Destroy(Object) GameController:Awake() (Filename:
> /Applications/buildAgent/work/d63dfc6385190b60/artifacts/iPhonePlayer-armv7Generated/UnityEngineDebug.cpp
> Line: 49)
>
> ExecutionEngineException: Attempting to JIT compile method
> 'PlayerData__TypeMetadata4:.ctor ()' while running with --aot-only.
>
> at System.Reflection.MonoCMethod.Invoke (System.Object obj,
> BindingFlags invokeAttr, System.Reflection.Binder binder,
> System.Object[] parameters, System.Globalization.CultureInfo culture)
> [0x00000] in <filename unknown>:0 Rethrow as
> TargetInvocationException: Exception has been thrown by the target of
> an invocation. at System.Reflection.MonoCMethod.Invoke
> (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder
> binder, System.Object[] parameters, System.Globalization.CultureInfo
> culture) [0x00000] in <filename unknown>:0 at
> System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr,
> System.Reflection.Binder binder, System.Object[] parameters,
> System.Globalization.CultureInfo culture) [0x00000] in <filename
> unknown>:0 at System.Reflection.ConstructorInfo.Invoke
> (System.Object[] parameters) [0x00000] in <filename unknown>:0 at
> System.Activator.CreateInstance (System.Type type, Boolean nonPublic)
> [0x00000] in <filename unknown>:0 at
> System.Activator.CreateInstance (System.Type type) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.CreateMemberTypeMetadata
> (System.Type type) [0x00000] in <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.GetObjectData
> (System.Object obj,
> System.Runtime.Serialization.Formatters.Binary.TypeMetadata& metadata,
> System.Object& data) [0x00000] in <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObject
> (System.IO.BinaryWriter writer, Int64 id, System.Object obj) [0x00000]
> in <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectInstance
> (System.IO.BinaryWriter writer, System.Object obj, Boolean
> isValueObject) [0x00000] in <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteQueuedObjects
> (System.IO.BinaryWriter writer) [0x00000] in <filename unknown>:0
> at
> System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectGraph
> (System.IO.BinaryWriter writer, System.Object obj,
> System.Runtime.Remoting.Messaging.Header[] headers) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize
> (System.IO.Stream serializationStream, System.Object graph,
> System.Runtime.Remoting.Messaging.Header[] headers) [0x00000] in
> <filename unknown>:0 at
> System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize
> (System.IO.Stream serializationStream, System.Object graph) [0x00000]
> in <filename unknown>:0 at GameController.Save () [0x00000] in
> <filename unknown>:0 at GameController.OnDisable () [0x00000] in
> <filename unknown>:0 UnityEngine.Object:Destroy(Object, Single)
> UnityEngine.Object:Destroy(Object) GameController:Awake()
将此代码放入场景脚本中的 Awake
或 Start
函数:
// Forces a different code path in the BinaryFormatter that doesn't rely on run-time code generation (which would break on iOS).
Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
默认情况下,Mono 二进制序列化程序使用 iOS 不支持的 JIT 编译。幸运的是,有一种方法(上面的代码)可以将其切换为使用反射。
证明/另见:
Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
在 Unity 编辑器中创建错误,例如:
"Environment" not found in namespace
经过数小时的搜索,我发现以下代码可以完美运行:
System.Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER","yes");
希望对您有所帮助。