有没有办法将引用的 MonoBehaviours 序列化为 JSON?

2024-01-04

假设我有一个名为ObjectA其中包含两个对象:ObjectsB and ObjectC.

[System.Serializable]
public ClassA
{
    public ClassB classB;
    public ClassC classC;

    public ClassA()
    {
        classB = new ClassB();
        classC = new ClassC();
    }
}

[System.Serializable]
public ClassB
{
    //Some fields.
}

[System.Serializable]
public ClassC
{
    //Some fields.
}

如果我序列化ObjectA到 JSON,ObjectB and ObjectC不要被序列化。这是我序列化后得到的ObjectA到 JSON:
{"_instanceB":{"instanceID":10480},"_instanceC":{"instanceID":10230}}
我需要将所有这些对象序列化到一个文件并将其本地保存在硬盘驱动器上,以便以后能够恢复它们的状态。我该怎么做?
我应该取回吗ClassB and ClassC from ClassA然后将它们单独序列化并保存?像这样的事情:

public void Save()
{
    //Get instances of ClassB and ClassC.
    ClassB classB = classA.GetClassB;
    ClassC classC = classA.GetClassC;

    //Generate different JSON for each class.
    string classA_JSON = JsonUtility.ToJson(classA);
    string classB_JSON = JsonUtility.ToJson(classB);
    string classC_JSON = JsonUtility.ToJson(classC);

    //Paths for saving locally.
    string pathForClassA = Path.Combine("C:\\", "classA.json");
    string pathForClassB = Path.Combine("C:\\", "classB.json");
    string pathForClassC = Path.Combine("C:\\", "classC.json");

    File.WriteAllText(pathForClassA, classA_JSON);
    File.WriteAllText(pathForClassB, classB_JSON);
    File.WriteAllText(pathForClassC, classC_JSON);
}

看起来很难看,它会为每个嵌套类生成一个新的 JSON 文件。我可以以某种方式序列化吗ClassA将其嵌套类包含到一个 JSON 文件中?

P.S.这是一个 Unity 项目ClassA, ClassB, and ClassC从获得MonoBehaviour. Since BinaryFormatter不支持MonoBehaviour我无法使用它。我唯一要做的就是将其序列化为 JSON。


我能否以某种方式将 ClassA(包括其嵌套类)序列化到一个 JSON 文件中?

是的,你可以,但这需要一些工作:

你可以有[Serializable]表示类别ClassB and ClassC并使用ISerializationCallbackReceiver界面 https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html用于填充和使用它们ClassA

像这样的东西

public class ClassB : MonoBehaviour
{
    [SerializeField] private float example1;
    [SerializeField] private string example2;
    // etc.

    public void SetUp(SerializableClassB values)
    {
        // set all values
        this.example1 = values.example1;
        this.example2 = values.example2;
        // etc.
    }

    public SerializableClassB GetSerializable()
    {
        var output = new SerializableClassB();

        output.example1 = this.example1;
        output.example2 = this.example2;
        // etc.

        return output;
    }
}

[Serializable]
public class SerializableClassB
{
    public float example1;
    public string example2;
    // etc
}

同样对于ClassC

public class ClassC : MonoBehaviour
{
    [SerializeField] private float example3;
    [SerializeField] private string example4;
    // etc.

    public void SetUp(SerializableClassC values)
    {
        // set all values
        example3 = values.example3;
        example4 = values.example4;
        // etc.
    }

    public SerializableClassC GetSerializable()
    {
        var output = new SerializableClassC();

        output.example3 = example3;
        output.example4 = example4;
        // etc.

        return output;
    }
}

[Serializable]
public class SerializableClassC
{
    public float example3;
    public string example4;
    // etc
}

Then in ClassA你可以做

public class ClassA : MonoBehaviour, ISerializationCallbackReceiver
{
    public ClassB _classB;
    public ClassC _classC;

    [SerializeField] private SerializableClassB _serializableClassB;
    [SerializeField] private SerializableClassC _serializeableClassC;


    public void OnBeforeSerialize()
    {
        // before writing to a Json get the information from the MonoBehaviours into the normal classes
        if(_classB) _serializableClassB = _classB.GetSerializable();
        if(_classC) _serializeableClassC = _classC.GetSerializable();

    }

    public void OnAfterDeserialize()
    {
        // after deserializing write the infromation from the normal classes into the MonoBehaviours
        if(_classB) _classB.SetUp(_serializableClassB);
        if(_classC) _classC.SetUp(_serializeableClassC);
    }
}

第二个巨大的优势(副作用)是,现在您还可以控制_classB and _classC直接在ClassA实例。这样您就可以在集中管理器类中修改 MonoBehaviour 值。

使用序列化为 json 后

private void Start()
{
    File.WriteAllText(Path.Combine(Application.streamingAssetsPath, "Test.txt"), JsonUtility.ToJson(this));
    AssetDatabase.Refresh();
}

你现在得到

{
    "_classB":{"instanceID":-6766},"_classC":{"instanceID":-6826},
    "_serializableClassB": {
            "example1":23.0,
            "example2":"54ththfghg"
    },
    "_serializeableClassC": {
            "example3":67.0,
            "example4":"567gffhgfhgf"
    }
}

相比于我将其更改为的示例

{
    "_classB":{"instanceID":-6766},"_classC":{"instanceID":-6826},
    "_serializableClassB": {
            "example1":47,
            "example2":"Hello"
    },
    "_serializeableClassC": {
            "example3":32.123,
            "example4":"World!"
    }
}

并使用从 json 开始反序列化

private void Start()
{
    JsonUtility.FromJsonOverwrite(File.ReadAllText(Path.Combine(Application.streamingAssetsPath, "Test.txt")), this);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有没有办法将引用的 MonoBehaviours 序列化为 JSON? 的相关文章

  • 使用静态类型代替变量

    当您的项目不使用命名空间时 有什么方法可以告诉编译器使用静态类型而不是变量吗 例如 我有一个名为 User 的类 它具有各种静态和非静态方法 假设调用了其中一个静态方法GetUser 我想称之为User GetUser 方法来自一个方法 该
  • 如何从 List 中的字符串中删除数字/数字?

    我有一个字符串列表 List
  • C++ 私有静态成员变量

    此 C 代码在编译时产生链接器错误 A h class A public static void f private static std vector
  • async wait 在调用异步方法时返回 Task> 而不是 List

    我正在尝试了解 async wait 的用法 并且研究了一些博客文章 现在我已经编写了一个测试代码 但它没有按照我期望的方式工作 我有一个返回列表的方法 private List
  • 以标准用户身份打开默认浏览器 (C++)

    我目前正在使用 ShellExecute 打开 在用户浏览器中打开 URL 但在 Win7 和 Vista 中遇到了一些麻烦 因为该程序作为服务运行提升 当 ShellExecute 打开浏览器时 它似乎读取 本地管理员 配置文件而不是用户
  • Create CFrameWnd 给出了第一次机会异常——为什么?

    我正在尝试使用基于 CFrameWnd 的代码编写一个简单的 MFC 应用程序 该应用程序在可滚动窗口中绘制 下面的代码改编自 Prosise Programming Windows with MFC 第 2 版 第 89ff 页 当我在调
  • 在 ncurses 中使用退格键

    我设置了一个简单的 ncurses 程序 它使用 getch 一次读取一个字符并将它们复制到缓冲区中 我遇到的问题是检测到按下退格键 这是相关代码 while buffer i c getch EOF i if c n break else
  • 如何让实体框架初始化新创建的实体上的集合?

    我正在尝试用一些测试数据来种子我的数据库IDatabaseIntialiser像这样 protected override void Seed BlogDataContext context
  • 使用互斥锁来阻止临界区外部的执行

    我不确定我的术语是否正确 但这里是 我有一个由多个线程使用的函数来写入数据 在注释中使用伪代码来说明我想要的内容 these are initiated in the constructor int data std atomic
  • 如何使用 libpq 获取双精度值?

    The examples http www postgresql org docs 9 3 interactive libpq example htmllibpq 文档中展示了如何通过将整数值转换为主机字节序表示来获取整数值 我很好奇必须做
  • SignTool 错误:访问被拒绝

    我尝试在安装了 VS2010 的 Windows Server 2008 R2 x64 上使用新的代码签名证书对 NET 应用程序进行authenticode 签名 但 SignTool 始终响应访问被拒绝 SignTool exe sig
  • 如何从代码隐藏中向我的 div 添加点击事件?

    如何从代码隐藏中向我的 div 添加点击事件 当我点击 div 时 会出现一个消息框 其中显示 您想删除它吗 并在框中显示 是 或 否 全部来自后面的代码 while reader Read System Web UI HtmlContro
  • 将文件读取为 JSON

    我想读取几个文件 index html style css main js 来创建用于上传的 JSON 有效负载 我知道使用 Nodejs 我可以开始创建我想要的东西 如下所示 var fs require fs fs readFile i
  • win32 API 和 .NET 框架之间的选择

    我必须开发一个适用于 Windows 的应用程序 该应用程序将能够通过网络摄像头识别手势来控制鼠标 我将使用 vc 2008 进行开发 但我很困惑是使用 NET 框架还是核心 win32 API 性能对于我的应用程序非常重要 根据 Ivor
  • 使用 roslyn 扩展 C# 语法

    我试图在没有 else 情况的情况下实现 return if return value if 因为我只想在条件有效时返回或返回一个值 我知道 有if condition return or if condition return value
  • 实体框架代理创建

    我们可以通过使用来停止在上下文构造函数中创建代理 this Configuration ProxyCreationEnabled false 在 EF 4 1 中创建代理有哪些优点和缺点 代理对于两个功能是必需的 延迟加载 导航属性在第一次
  • 致命错误 C1001:编译器中发生内部错误(编译器文件“msc1.cpp”,第 1325 行)

    当我编译代码时 错误指向以下类 该错误在两行上突出显示 如下所示 tm validFrom tm validUntil struct t SslCertData final struct t Contact TCHAR Organizati
  • FakeItEasy 代理方法调用实际实现

    我正在尝试将对假对象的调用代理到实际的实现 这样做的原因是我希望能够使用 Machine Specifications 的 WasToldTo 和 WhenToldTo 它们仅适用于接口类型的伪造 因此 我正在执行以下操作来代理对我的真实对
  • 什么时候使用静态库需要头文件?

    如果我在 Linux 中用 C 创建一个静态库并生成 a 文件 我 或其他人 如何使用该库 例如 我的库定义了一个类 我认为仅仅提供 a 文件是不够的 还需要提供头文件 我如何知道 a 文件必须提供哪些头文件 例如 我是否需要提供我的库代码
  • 如何将 char 转换为 unsigned int?

    我有一个字符数组 它实际上用作字节数组 而不是用于存储文本 在数组中 有两个特定字节表示我需要存储到无符号 int 值中的数值 下面的代码解释了设置 char bytes bytes 2 bytes 0 0x0C For the sake

随机推荐

  • Numpy 和 matplotlib 垃圾收集

    我有一个 python 脚本 它对不同的参数进行许多模拟 Q K 绘制结果并将其存储到磁盘 每组参数 Q K 生成 200x200x80 数据点的 3D 体积网格 这需要约 100 MB 的数据 然后逐层绘制该体积网格的一部分 生成约 60
  • 将参数绑定到信号/槽

    我基本上有多个事件信号 我想将它们连接到同一个插槽 我想知道的是如何将基于字符串的参数传递到同一插槽 以便该插槽知道该信号来自哪个信号 一种替代方法是制作与信号一样多的槽 然后以 1 1 的方式连接它们 但考虑到所有处理的代码非常相似 这种
  • 在 R 中生成滞后时间序列横截面变量

    我是 R 新用户 我有一个时间序列横截面数据集 尽管我已经找到了滞后时间序列数据的方法R 我还没有找到创建滞后时间序列横截面变量的方法 以便我可以在分析中使用它们 以下是您可以如何使用lag 功能与zoo 和面板系列数据 gt librar
  • 远程主机标识已更改?

    NPM 表示可能存在安全错误 meteor npm install mui system npm ERR Error while executing npm ERR usr local bin git ls remote h t ssh e
  • 开始创建自定义视图过渡

    我正在寻找有关创建自定义视图转换的教程 特别是 涉及除受影响的 UIView 之外的元素的转换 例如在转换发生时播放动画或修改正在转换的 UIView 的屏幕截图 我并不是指实现一组基本的过渡 幻灯片 淡入淡出等 苹果网站上有很多相关示例
  • 如何以相同的方式对两个数组进行排序?

    我希望输出为 3 0 2 36 1 1 键和以相同方式排序的值 three one two fun main var l 0 var letters arrayOf one two three var digits arrayOf 2 36
  • hadoop 空指针异常

    我正在尝试设置一个hadoop的多节点集群迈克尔 诺尔的方式 http www michael noll com tutorials running hadoop on ubuntu linux multi node cluster 使用两
  • Dockerfile 中 RUN 和 CMD 的区别

    我很困惑什么时候应该使用CMD vs RUN 例如 执行 bash shell 命令 即ls la 我总是会使用CMD或者有什么情况我会使用RUN 试图了解这两个类似的最佳实践Dockerfile指令 RUN https docs dock
  • 在 IIS 6 中的应用程序级别设置 NTAuthenticationProviders

    我在 IIS 中有以下结构 Internet Information Services local computer Web Sites Default Web Site MyApplication MyApplication是 IIS 中
  • 无法在脚本模块中创建 PowerShell 别名

    重现步骤 使用以下函数和别名在 WindowsPowerShell Modules TestAlias TestAlias psm1 中创建 TestAlias 模块 function foo write output foo New Al
  • 将 defaultdict(list) 写入文件

    之前问过一个问题使用defaultdict解析多分隔符文件 https stackoverflow com questions 46264408 using defaultdict to parse multi delimiter file
  • 在 Glassfish 中导入 ssl 证书

    我有以下问题 我从 comodo 为我的 glassfish Web 应用程序获得了免费证书 90 天 然后我通过以下方式将证书导入 glassfish 3 1http javadude wordpress com 2010 04 06 g
  • 如何在不使用 UITableViewDiffableDataSource 删除和插入的情况下重新加载项目?

    我正在使用我的应用程序中实现搜索屏幕UITableViewDiffableDataSource 每个单元格代表一个搜索命中 并在单元格标题中突出显示搜索匹配 有点像 Xcode 的 快速打开 窗口突出显示其结果项的部分内容 当在搜索字段中输
  • 字符串文字中 Informix JDBC、MONEY 和小数点分隔符的问题

    我在使用 MONEY 数据类型的 JDBC 应用程序时遇到问题 当我插入 MONEY 列时 insert into money test amt values 123 45 我得到了例外 Character to numeric conve
  • 为什么不可能窃取访问令牌?

    我正在学习 OAuth 我脑子里有一个问题 我找不到答案 我理解请求令牌是否授权应用程序使用 API 但是 一旦用户获得了访问令牌 如果有人窃取了他的访问令牌 会发生什么情况 想象一下我们有类似的东西http www example com
  • 如何在不运行测试的情况下获取所有标签和黄瓜场景

    我想以某种方式获取我在项目中使用的所有标签的列表 并获取我在项目中没有运行测试的黄瓜场景的所有名称 有人可以帮助我我该怎么做吗 根据 mpkorstanje的建议 您可以为此创建一个自定义插件 public class DryRunPlug
  • 如何测试MySQL事务?

    我有一个关于测试事务中的查询的问题 我使用 MySQL 事务已经有一段时间了 每次我这样做时 我都会使用类似的东西 doCommit true error mysql query BEGIN repeat this part with th
  • Object方法中的“this”关键字指向Window

    var name The Window var object name My Object getNameFunc function return function return this name console log object g
  • 如何使用 Reactor 3.x 将 List 转换为 Flux

    我有一个异步调用节俭接口 public CompletableFuture
  • 有没有办法将引用的 MonoBehaviours 序列化为 JSON?

    假设我有一个名为ObjectA其中包含两个对象 ObjectsB and ObjectC System Serializable public ClassA public ClassB classB public ClassC classC