unity3d - 将 Unity 预制件/场景反序列化为键/值对的嵌套哈希表
问题描述
我正在尝试编写一个工具来扫描我们的 Unity (2017.4.22) 预制件和场景文件,以查找发布版本中不存在的 Monobehaviour 属性。我创建了 ac# 控制台项目(包含 YamlDotNet 6.1.2),并且从这个项目中我参考了 Unity 的“Assembly-CSharp-firstpass.dll”和“Assembly-CSharp.dll”dll。
我想知道是否有人能够配置 YamlDotNet 将任何给定的预制/场景文件解析为内存中的通用键/值数据结构(具有任意数量的嵌套级别),因此我可以对其进行迭代并使用反射来确定是否字段存在。
如果您想知道为什么我需要手动执行此操作,那是因为我正在扫描发布版本中不存在的字段。唯一的方法是重新编译“Assembly-CSharp-firstpass”和“Assembly-CSharp”,删除 UNITY_EDITOR(以及“Editor”子文件夹中文件的所有代码)。我不能在编辑器中执行此操作(显然),所以这就是为什么它必须是一个独立的工具。
我尝试过的一切都导致崩溃。这是我尝试过的:
- 我下载了 YamlDotNet 6.1.2 源码
- 尝试使用 Deserialize(...) 反序列化预制件。收到此错误:“遇到未解析的标签 'tag:unity3d.com,2011:1'”
- 然后我找到了我集成的这个自定义类型解析器:https ://gist.github.com/derFunk/795d7a366627d59e0dbd
- 然后我开始收到这个异常:“反序列化过程中的异常---> System.InvalidOperationException:无法创建'UnityEngine.GameObject'类型的实例”
我猜这是因为我试图在一个不完全支持 GameObjects 的环境中实例化一个 GameObject(毕竟我在一个独立的 C# 项目中)。
但我实际上不需要实例化任何游戏对象。我只想解析这些值。这对任何人都有意义吗?我在这里发现了一些其他问题,但它们似乎无法处理与 Unity 预制件具有相同复杂性的 YAML 文件。
在此先感谢,杰夫
解决方案
你的猜测是正确的。因为您将tag:unity3d.com,2011:*
标签解析为UnityEngine.GameObject
相关类型,所以反序列化器在遇到标签时会尝试创建相应类型的实例。
您可以选择始终将标签解析为Dictionary<string, object>
(或者Dictionary<object, object>
如果键并不总是字符串)。然后总是得到字典。
在您的情况下,使用加载 YAML 流可能更简单YamlDotNet.RepresentationModel.YamlStream
。这将为您提供更适合您的用例的 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;
推荐阅读
- django - 从 Django REST Framework 获取数据到 Vue 并从不同组件调用数据
- swift - 当单个非滚动项在 VStack 中时,SwiftUI 不会折叠导航栏
- c++ - 即使我确定指定的路径是正确的,QTranslator 似乎也找不到我的 .ls 文件
- sql - 如何使用 EXIST 报告已完成工作支付的所有发票与未结发票?
- angular - 反应形式在 Ionic Modal 的视图中不显示值
- python - 在 Mac OS X 上使用 Jupyter Notebook 没有名为“pandas”的模块问题
- ios - NavigationView 变为空白,从导航链接的详细视图重复转换
- c++ - Cleaning code for move generator function for game in c++
- javascript - MongoDB在对象数组中查找匹配文档并更新匹配字段
- vue.js - 为什么 Jest spyOn() 只通过了其中一个测试,而在另一个测试中失败了?