如何在 Unity 中序列化和反序列化包含 Gameobject 和 Vector2 的字典

2024-03-18

我正在为一个游戏制作一个关卡编辑器,可以在统一的编辑模式下编辑关卡。它最终保存了进度,可以在游戏运行时加载回来,但事实证明您无法通过 Unity 序列化 Unity 的 Gameobject 或任何自定义 C# 对象(即使它这么说)。我能够序列化大部分内容,但只能使用一个 Dictionary 对象。

现在,问题来了。

[HideInInspector] public Dictionary<GameObject, Vector2> occupants;

它包含 GameObject 和 Vector2 的字典(Vector 2 是 2d 网格中的位置,而不是 2d 空间中的位置)。它们都不能通过正常方法序列化。

 public static void SaveDataValues(DataValuesToSave dataValues, string level)
 {
     BinaryFormatter formatter = new BinaryFormatter();
     string path = Application.persistentDataPath + level + ".dat";
     FileStream stream = new FileStream(path, FileMode.Create);

     DataValuesToSave data = dataValues;

     formatter.Serialize(stream, data);
     stream.Close();
 }

我怎样才能序列化这个字典?任何建议,将不胜感激。


总的来说:你不应该使用BinaryFormatter anymore https://learn.microsoft.com/dotnet/standard/serialization/binaryformatter-security-guide at all!


您可以构建一个包装类来实现ISerializationCallbackReceiver https://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.html界面。在他们的示例中,甚至有几乎与您完全相同的用例!

稍微修改一下的解决方案可能看起来像例如

[Serializable]
public class YourDictionary: Dictionary<GameObject, Vector2>, ISerializationCallbackReceiver
{
    [HideInInspector][SerializeField] private List<GameObject> _keys = new List<GameObject>();
    [HideInInspector][SerializeField] private List<Vector2> _values = new List<Vector2>();

    public void OnBeforeSerialize()
    {
        _keys.Clear();
        _values.Clear();
    
        foreach (var kvp in this)
        {
            _keys.Add(kvp.Key);
            _values.Add(kvp.Value);
        }
    }
    
    public void OnAfterDeserialize()
    {
        Clear();
    
        for (var i = 0; i != Math.Min(_keys.Count, _values.Count); i++)
        {
            Add(_keys[i], _values[i]);
        }
    }
}

通过这种方式,您可以保留字典及其接口的全部功能,但只需在顶部添加序列化即可。

然后在你使用的其他脚本中

[HideInInspector] public YourDictionary occupants;

并像使用它一样Dictionary<GameObject, Vector2>(我是说Add, Remove, Clear, foreach etc).


现在它正在发挥作用。我只是使用了这个简单的测试脚本

public class NewBehaviourScript : MonoBehaviour
{
    public GameObject obj;
    
    [HideInInspector] public YourDictionary occupants;

    [ContextMenu(nameof(Add))]
    private void Add()
    {
        Vector2 vec = obj.transform.position;
        occupants.Add(obj, vec);
    }

    [ContextMenu(nameof(Apply))]
    private void Apply()
    {
        foreach (var kvp in occupants)
        {
            kvp.Key.transform.position = kvp.Value;
        }
    }

    [ContextMenu(nameof(Remove))]
    private void Remove()
    {
        occupants.Remove(obj);
    }
}

现在可以愉快地存储、删除和应用场景中对象的位置;)

  • 我首先存储 4 个物体的位置。
  • 然后我将它们移到其他地方并保存场景
  • 我卸载场景并创建一个新的空场景
  • 我加载原始场景
  • Result点击“应用”后,所有对象都回到原位,这意味着字典已成功(反)序列化;)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Unity 中序列化和反序列化包含 Gameobject 和 Vector2 的字典 的相关文章

  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 获取没有非标准端口的原始 url (C#)

    第一个问题 环境 MVC C AppHarbor Problem 我正在调用 openid 提供商 并根据域生成绝对回调 url 在我的本地机器上 如果我点击的话 效果很好http localhost 12345 login Request
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • WPF TabControl,用C#代码更改TabItem的背景颜色

    嗨 我认为这是一个初学者的问题 我搜索了所有相关问题 但所有这些都由 xaml 回答 但是 我需要的是后台代码 我有一个 TabControl 我需要设置其项目的背景颜色 我需要在选择 取消选择和悬停时为项目设置不同的颜色 非常感谢你的帮助
  • 如何返回 json 结果并将 unicode 字符转义为 \u1234

    我正在实现一个返回 json 结果的方法 例如 public JsonResult MethodName Guid key var result ApiHelper GetData key Data is stored in db as v
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • 如何将图像路径保存到Live Tile的WP8本地文件夹

    我正在更新我的 Windows Phone 应用程序以使用新的 WP8 文件存储 API 本地文件夹 而不是 WP7 API 隔离存储文件 旧的工作方法 这是我如何成功地将图像保存到 共享 ShellContent文件夹使用隔离存储文件方法
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • WCF:将随机数添加到 UsernameToken

    我正在尝试连接到用 Java 编写的 Web 服务 但有些东西我无法弄清楚 使用 WCF 和 customBinding 几乎一切似乎都很好 除了 SOAP 消息的一部分 因为它缺少 Nonce 和 Created 部分节点 显然我错过了一
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • ASP.NET MVC 6 (ASP.NET 5) 中的 Application_PreSendRequestHeaders 和 Application_BeginRequest

    如何在 ASP NET 5 MVC6 中使用这些方法 在 MVC5 中 我在 Global asax 中使用了它 现在呢 也许是入门班 protected void Application PreSendRequestHeaders obj
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 防止索引超出范围错误

    我想编写对某些条件的检查 而不必使用 try catch 并且我想避免出现 Index Out of Range 错误的可能性 if array Element 0 Object Length gt 0 array Element 1 Ob

随机推荐

  • 大型 Grails 项目中的集成和单元测试

    由于必须处理模拟对象 因此编写单元测试通常比大型 Grails 项目中的集成测试更复杂 这article https www ibm com developerworks java library j grails10148 甚至建议我们甚
  • 如何让 ReadJson 返回“默认”行为 - 就好像 CanConvert 返回 false

    我已经创建了一个实现JsonConverter CanConvert总是返回 true In ReadJson我有时想只使用 默认 行为 就好像CanConvert返回错误 我的ReadJson从未被调用过 其他各种帖子建议我做以下一些变化
  • 如何使用 VSCode 和多个 java 版本

    我工作的所有公司项目都使用 Java 8 但是我想尝试使用 VSCode for Java 问题是它要求我使用 Java 11 才能使 Java 扩展工作 另外我想开始使用 java 11 做个人项目 现在在路径 windows环境 中 我
  • 获取组的所有成员 - 传递

    是否有对图形 API 的调用可以将组的所有成员返回给我 包括嵌套组的用户 要获取组的所有直接成员 有GetGroupMembers https msdn microsoft com en us library azure ad graph
  • Angular2单元测试-为什么nativeElement有空的CSSStyleDeclaration

    我正在尝试测试一个简单的标头组件 它有一个按钮 当聚焦时 仅使用 css 可见性属性打开一个下拉列表 这是 HTML
  • 将 Glassfish v2 升级到 JPA 2.0?

    我尝试在 Glassfish V2 上将 Hibernate 3 5 5 与 Spring HibernateJpaVendorAdapter 一起使用 但在初始化 Spring 上下文时出现以下异常 java lang NoSuchMet
  • 合并两个表 (CSV) if (表 1 列 A == 表 2 列 A)

    我有两个 CSV 可在 Numbers 或 Excel 中打开 结构如下 word num1 and word num2 如果这两个词相等 就像它们都是 hi 和 hi 我希望它变成 word num1 num2 这是一些图片 就像第一行一
  • 在 LINQ to SQL 中搜索两列?

    我正在尝试在 Visual Studio 中使用 LINQ to SQL 创建一个简单的搜索方法 在我的数据库中 我有字段 名字 和 姓氏 我的搜索字符串是 名称 如何创建一个简单的 LINQ 查询来搜索这两个字段 在普通 SQL 中我会做
  • 访问 Lithium 中的多个模型深层关系

    是否有可能在 Lithium 中访问多个深入关系的模型 例如 我有一个用户模型 class Users extends lithium data Model public validates array public belongsTo a
  • 字节变量上的Python3正则表达式[重复]

    这个问题在这里已经有答案了 我正在尝试对 bytes 变量执行正则表达式替换 但收到错误 sequence item 0 expected a bytes like object str found 这是一个使用 python3 重现问题的
  • 更新 xCode/Xamarin 后,构建时出现 MT5306 错误

    更新我的 Xamarin Xcode 后 我不断收到以下错误 无法创建 fat 文件 请查看构建日志 MT5306 经过一段时间的挣扎 我终于发现打开我的 xCode 并接受新的使用条款为我解决了这个问题 我可以再次构建我的项目 我认为这可
  • 如何使用java编程将一种语言翻译成另一种语言[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 在我的项目中 有一个内容部分 用户可以在其中查看四种不同语言的内容 有没有什么办法 我把内容放在一种语言中 并根据用户的选择 我的ja
  • Android 像 Iphone 一样设置启动屏幕(Activity)第 2 部分

    在获得仅调用一次我的启动活动的解决方案后 第1部分问题 https stackoverflow com questions 16163365 android setting up splash screenactivity like iph
  • 每行都有不同的钻取

    我有一份 SSRS 报告 其中包含多个级别的深入研究 数据针对顶级视图进行聚合 但我需要根据其中一列的类型显示不同的向下钻取报告 Eg 表 1 苹果 Name Cost Fuji 1 5 Gala 3 5 表 2 南瓜 Name Cost
  • 如何设置 ListFragment 的 ListView 的样式

    我想保留这些方法 setListShown true setListShownNoAnimation true 但如果我用 onCreateView LayoutInflater inflater ViewGroup container B
  • 使用扫描仪继续读取数字,直到到达换行符

    我想从控制台读取几个数字 我想要做到这一点的方法是让用户输入一系列由空格分隔的数字 代码执行以下操作 Scanner sc new Scanner System in while sc hasNextInt int i sc nextInt
  • Android上的Crosswalk从java调用js函数

    我正在尝试使用人行横道 https crosswalk project org我的 Android 应用程序中的运行时 我在 Android 4 上尝试过这个 我得到了一些 js 和 html 代码 它非常适合我 但它不像 android
  • webview中点击URL时如何获取文件名

    当我们在页面中提供该文件的链接时 如何获取我们上传到服务器上的文件名 我正在做的是 我在 webview 中提供带有文件链接的数据 因此每当用户单击链接时都需要从服务器下载 因为我已经从服务器下载了该文件 但问题是无法使用 Download
  • Namenode-HDFS 出现“连接被拒绝”错误(Hadoop 问题)

    当我们看到使用时 我的所有节点都已启动并运行jps命令 但我仍然无法连接到 hdfs 文件系统 每当我点击Browse the filesystem在 Hadoop Namenode localhost 8020 页面上 我得到的错误是Co
  • 如何在 Unity 中序列化和反序列化包含 Gameobject 和 Vector2 的字典

    我正在为一个游戏制作一个关卡编辑器 可以在统一的编辑模式下编辑关卡 它最终保存了进度 可以在游戏运行时加载回来 但事实证明您无法通过 Unity 序列化 Unity 的 Gameobject 或任何自定义 C 对象 即使它这么说 我能够序列