将 Unity prefab/scene 反序列化为 key/value 对的嵌套哈希表
Deserializing a Unity prefab/scene as nested hashtable of key/value pairs
我正在尝试编写一个工具来扫描我们的 Unity (2017.4.22) 预制件和场景文件,以查找发布版本中不存在的 Monobehaviour 属性。我创建了一个 c# 控制台项目(包含 YamlDotNet 6.1.2),从这个项目中我引用了 Unity 的 'Assembly-CSharp-firstpass.dll' 和 'Assembly-CSharp.dll' dll。
我想知道是否有人能够配置 YamlDotNet 以将任何给定的 prefab/scene 文件解析为内存中的通用 key/value 数据结构(具有任意数量的嵌套级别),所以我可以迭代它并使用反射来确定字段是否存在。
如果您想知道为什么我需要手动执行此操作,那是因为我正在扫描发布版本中不存在的字段。唯一的方法是重新编译 'Assembly-CSharp-firstpass' 和 'Assembly-CSharp' 并删除 UNITY_EDITOR(以及 'Editor' 子文件夹中文件中的所有代码)。我不能在编辑器中执行此操作(显然),所以这就是为什么它必须是一个独立的工具。
我尝试过的一切都导致了崩溃。这是我尝试过的:
- 我下载了 YamlDotNet 6.1.2 源码
- 尝试使用 Deserialize(...) 反序列化预制件。收到此错误:"Encountered an unresolved tag 'tag:unity3d.com,2011:1'"
- 然后我找到了这个我集成的自定义类型解析器:https://gist.github.com/derFunk/795d7a366627d59e0dbd
- 然后我开始收到这个异常:"Exception during deserialization ---> System.InvalidOperationException: Failed to create an instance of type 'UnityEngine.GameObject'"
我猜这是因为我试图在不完全支持游戏对象的环境中实例化游戏对象(毕竟我在独立的 C# 项目中)。
但实际上我不需要实例化任何游戏对象。我只想解析这些值。这对任何人都有意义吗?我在这里发现了一些其他问题,但它们似乎无法处理与 Unity 的预制件具有相同复杂性的 YAML 文件。
提前致谢,
杰夫
你猜对了。因为您正在将 tag:unity3d.com,2011:*
标签解析为 UnityEngine.GameObject
和相关类型,所以反序列化器会在遇到标签时尝试创建相应类型的实例。
您可以选择始终将标记解析为 Dictionary<string, object>
(如果键不总是字符串,则为 Dictionary<object, object>
)。然后总是得到字典。
在您的情况下,使用 YamlDotNet.RepresentationModel.YamlStream
加载 YAML 流可能更简单。这将为您提供更适合您的用例的 YAML 文档表示。
下面是官方示例:https://github.com/aaubry/YamlDotNet/wiki/Samples.LoadingAYamlStream
// Load the stream
var yaml = new YamlStream();
yaml.Load(input);
// Examine the stream
var mapping = (YamlMappingNode)yaml.Documents[0].RootNode;
我正在尝试编写一个工具来扫描我们的 Unity (2017.4.22) 预制件和场景文件,以查找发布版本中不存在的 Monobehaviour 属性。我创建了一个 c# 控制台项目(包含 YamlDotNet 6.1.2),从这个项目中我引用了 Unity 的 'Assembly-CSharp-firstpass.dll' 和 'Assembly-CSharp.dll' dll。
我想知道是否有人能够配置 YamlDotNet 以将任何给定的 prefab/scene 文件解析为内存中的通用 key/value 数据结构(具有任意数量的嵌套级别),所以我可以迭代它并使用反射来确定字段是否存在。
如果您想知道为什么我需要手动执行此操作,那是因为我正在扫描发布版本中不存在的字段。唯一的方法是重新编译 'Assembly-CSharp-firstpass' 和 'Assembly-CSharp' 并删除 UNITY_EDITOR(以及 'Editor' 子文件夹中文件中的所有代码)。我不能在编辑器中执行此操作(显然),所以这就是为什么它必须是一个独立的工具。
我尝试过的一切都导致了崩溃。这是我尝试过的:
- 我下载了 YamlDotNet 6.1.2 源码
- 尝试使用 Deserialize(...) 反序列化预制件。收到此错误:"Encountered an unresolved tag 'tag:unity3d.com,2011:1'"
- 然后我找到了这个我集成的自定义类型解析器:https://gist.github.com/derFunk/795d7a366627d59e0dbd
- 然后我开始收到这个异常:"Exception during deserialization ---> System.InvalidOperationException: Failed to create an instance of type 'UnityEngine.GameObject'"
我猜这是因为我试图在不完全支持游戏对象的环境中实例化游戏对象(毕竟我在独立的 C# 项目中)。
但实际上我不需要实例化任何游戏对象。我只想解析这些值。这对任何人都有意义吗?我在这里发现了一些其他问题,但它们似乎无法处理与 Unity 的预制件具有相同复杂性的 YAML 文件。
提前致谢, 杰夫
你猜对了。因为您正在将 tag:unity3d.com,2011:*
标签解析为 UnityEngine.GameObject
和相关类型,所以反序列化器会在遇到标签时尝试创建相应类型的实例。
您可以选择始终将标记解析为 Dictionary<string, object>
(如果键不总是字符串,则为 Dictionary<object, object>
)。然后总是得到字典。
在您的情况下,使用 YamlDotNet.RepresentationModel.YamlStream
加载 YAML 流可能更简单。这将为您提供更适合您的用例的 YAML 文档表示。
下面是官方示例:https://github.com/aaubry/YamlDotNet/wiki/Samples.LoadingAYamlStream
// Load the stream
var yaml = new YamlStream();
yaml.Load(input);
// Examine the stream
var mapping = (YamlMappingNode)yaml.Documents[0].RootNode;