【问题标题】:Unity C# InvalidCastException: Cannot cast from source type to destination typeUnity C# InvalidCastException:无法从源类型转换为目标类型
【发布时间】:2017-06-20 05:48:31
【问题描述】:

我目前在大型项目中遇到错误。

代码如下:

public void SaveFileExists(){

    Debug.Log ("SaveFileExists was called.");

    //GameObject.Find ("_Scripts").GetComponent<SaveGame> ().Load ();
    UserData userdata = null;

    //Creating a new BinaryFormatter
    BinaryFormatter bf = new BinaryFormatter ();

    //Making a file which now contains the Un-Serialized File
    FileStream file = File.Open (Application.persistentDataPath + ("/UserData." + accountLoginAttempt), FileMode.Open);

    //Assigning the values of the saved file to the new file
    //UserData newData = (UserData)bf.Deserialize (file);

    userdata = bf.Deserialize(file) as UserData;

    //Assigning the values from the save file to the variables in this script.
    accountLoginAttempt = userdata.username;
    accountLevel = userdata.userlevel;

    //Assinging the values from this script to the _PlayerManager script. (This is where the UI gets it's info).
    GameObject.Find ("_AccountInfoSaveHolder").GetComponent<HoldInfo> ().UserInfo = accountLoginAttempt;
    GameObject.Find ("_AccountInfoSaveHolder").GetComponent<HoldInfo> ().UserLevel = accountLevel;

    errortext.text = "Login Successful.";
    Canvas.ForceUpdateCanvases ();
}

序列化的字段也在下面:

[System.Serializable]
class UserData{
public string username;
public int userlevel;
}

我正在尝试加载存储在 Application.persistentDataPath 中的保存文件。将 UserData.username 和 UserData.userlevel 分配给我脚本中的变量。

我收到的错误是:

InvalidCastException:无法从源类型转换到目标 输入。

更多详情:

LoginScript.SaveFileExists() (在 资产/脚本/AccountSystem/LoginScript.cs:126) LoginScript.OnLoginClick () (在 资产/脚本/AccountSystem/LoginScript.cs:104) UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (在 /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:153) UnityEngine.Events.InvokableCallList.Invoke (System.Object[] 参数)(在 /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:634) UnityEngine.Events.UnityEventBase.Invoke(System.Object[] 参数) (在 /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:769) UnityEngine.Events.UnityEvent.Invoke () (在 /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53) UnityEngine.UI.Button.Press () (在 /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35) UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData)(在 /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44) UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler 处理程序,UnityEngine.EventSystems.BaseEventData eventData)(在 /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52) UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject 目标,UnityEngine.EventSystems.BaseEventData eventData,UnityEngine.EventSystems.EventFunction`1 函子)(在 /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269) UnityEngine.EventSystems.EventSystem:Update()

编辑:

SaveGame.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary; 
using System.IO;
using UnityEngine.SceneManagement;

public class SaveGame : MonoBehaviour {

//Saved Variables
[Header("Saved Variables")]
public string savedname;
public string attemptedlogin;
public int savedlevel;

//Loaded Variables
[Header("Loaded Variables")]
public string loadedname;
public int loadedlevel;


public void Awake(){

    if (SceneManager.GetActiveScene ().name == "GameScene") {
        Load ();
    }
}

public void Save(){

    savedname = GameObject.Find ("_Scripts").GetComponent<PlayerManager> ().PlayerName;
    savedlevel = GameObject.Find ("_Scripts").GetComponent<PlayerManager> ().UserLevel;

    BinaryFormatter bf = new BinaryFormatter();

    FileStream file = File.Open(Application.persistentDataPath + ("/UserData." + savedname), FileMode.Create);

    UserData newData = new UserData();

    newData.username = savedname;
    newData.userlevel = savedlevel;

    bf.Serialize(file, newData);
    file.Close();
}
}

我还删除了整个脚本中的所有 System.Serializable 类,并制作了一个名为 UserDataSerialize.cs 的脚本,其中包含:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
class UserData{
    public string username;
    public int userlevel;
}

现在我得到的错误是:

TypeLoadException: Could not load type 'SaveGame+UserData'.
System.Reflection.Assembly.GetType (System.String name, Boolean throwOnError, Boolean ignoreCase) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/Assembly.cs:398)
System.Reflection.Assembly.GetType (System.String name, Boolean throwOnError) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/Assembly.cs:381)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetDeserializationType (Int64 assemblyId, System.String className) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:833)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadTypeMetadata (System.IO.BinaryReader reader, Boolean isRuntimeObject, Boolean hasTypeInfo) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:637)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectInstance (System.IO.BinaryReader reader, Boolean isRuntimeObject, Boolean hasTypeInfo, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:269)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject (BinaryElement element, System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:195)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject (BinaryElement element, System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:223)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject (BinaryElement element, System.IO.BinaryReader reader) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:130)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph (BinaryElement elem, System.IO.BinaryReader reader, Boolean readHeaders, System.Object& result, System.Runtime.Remoting.Messaging.Header[]& headers) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:104)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:179)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:136)
LoginScript.SaveFileExists () (at Assets/Scripts/AccountSystem/LoginScript.cs:111)
LoginScript.OnLoginClick () (at Assets/Scripts/AccountSystem/LoginScript.cs:84)
UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:153)
UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:634)
UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:769)
UnityEngine.Events.UnityEvent.Invoke () (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53)
UnityEngine.UI.Button.Press () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
UnityEngine.EventSystems.EventSystem:Update()

【问题讨论】:

  • 唯一的显式转换是BinaryFormatter.Deserialize 到类型UserData 的结果。您确定文件是您期望的格式吗?
  • @AndyLamb 我这么认为?您所期望的格式到底是什么意思。 'UserData' 类是一个字符串 'username' 后跟一个 int 'userlevel'。
  • 你的 Unity 版本是多少?你也可以把你的保存代码放在你的问题中吗?
  • Mac 上的 Unity 5.5.1f1 个人版(64 位)。 SaveGame.cs: public void InitializeSave(){ savedname = GameObject.Find ("_Scripts").GetComponent ().PlayerName; savedlevel = GameObject.Find ("_Scripts").GetComponent ().UserLevel;节省 (); } 更多代码在下一条评论中
  • 第 2 部分 public void Save(){ BinaryFormatter bf = new BinaryFormatter(); //在保存路径的目录下创建一个新文件。 FileStream 文件 = File.Open(Application.persistentDataPath + ("/UserData." + savedname), FileMode.Create); //清除临时文件并从新文件开始 UserData newData = new UserData(); //分配变量 newData.username = savedname; newData.userlevel = 已保存级别; //将newData编码为文件。 bf.Serialize(文件,新数据);文件。关闭(); }

标签: c# class unity3d serialization loading


【解决方案1】:

解决方案:

创建另一个仅包含以下内容的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
class UserData{
    public string username;
    public int userlevel;
}

并在其他脚本中删除所有其他同名的 System.Serialize 类。

【讨论】:

  • 太棒了。有趣的是,它在 Unity 5.6 中是如何工作的,但在 5.5 中却不行。我猜 Unity 已经解决了这个问题。
【解决方案2】:

也许对每个人来说都不是问题,但这对我有帮助:在构建我的保存结构的过程中,我首先保存了一种类型的对象,然后切换到不同的对象。我的游戏设置为在有机会保存之前加载,所以我加载了一个旧类,而没有用新类保存它。我能够通过禁用加载、玩游戏一回合、保存然后再次打开加载来解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    相关资源
    最近更新 更多