bytes_to_var_with_objects
2026/4/15大约 3 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — bytes_to_var_with_objects
bytes_to_var_with_objects
定义
bytes_to_var_with_objects() 是 var_to_bytes_with_objects() 的逆操作——它把一段之前打包好的字节数据还原回原来的值,包括其中包含的对象引用。
继续用快递的比喻:你朋友收到了你寄出去的包裹(字节数组),现在需要拆开它。如果包裹里附带了"回寄地址卡片"(对象引用),就需要用这个"带地址拆包器"来打开,而不是普通的拆包器。bytes_to_var_with_objects() 会把字节数据还原成原始的数据结构,并且把里面保存的对象引用重新指向内存中仍然存在的那个对象。
简单来说:var_to_bytes_with_objects() 负责"打包",bytes_to_var_with_objects() 负责"拆包",它们必须成对使用。
函数签名
C#
// C# 中可使用 GodotObject 的静态方法
public static Variant BytesToVarWithObjects(byte[] bytes)
// 也可通过 GD 全局访问
Variant restored = GD.BytesToVarWithObjects(bytes);GDScript
func bytes_to_var_with_objects(bytes: PackedByteArray) -> Variant参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
bytes | PackedByteArray | 是 | 由 var_to_bytes_with_objects() 生成的字节数组,不能混用 var_to_bytes() 生成的数据 |
返回值
Variant —— 反序列化后的值。数据结构和原始值完全一致,包括其中的对象引用。如果原始对象已被销毁,对应的引用会变成 null。
代码示例
C#
using Godot;
public partial class BytesToVarWithObjectsExample : Node
{
public override void _Ready()
{
// 第一步:准备一个包含对象引用的数据,然后打包
var _playerNode = GetNode<Node>("Player");
var _originalData = new Godot.Collections.Dictionary
{
["player_ref"] = _playerNode,
["score"] = 999,
["items"] = new Godot.Collections.Array { "剑", "盾", "药水" }
};
// 打包成字节数组
byte[] _packed = GD.VarToBytesWithObjects(Variant.From(_originalData));
GD.Print($"打包完成,字节长度: {_packed.Length}");
// 第二步:从字节数组还原
var _restoredData = (Godot.Collections.Dictionary)GD.BytesToVarWithObjects(_packed);
// 验证还原结果
GD.Print($"分数: {_restoredData["score"]}"); // 999
GD.Print($"物品: {_restoredData["items"]}"); // ["剑", "盾", "药水"]
// 对象引用也还原了,指向同一个节点实例
var _restoredRef = (Node)_restoredData["player_ref"];
GD.Print($"还原的节点名: {_restoredRef.Name}"); // Player
// 实际场景:从网络收到的字节数据还原游戏状态
// byte[] networkData = ReceiveFromNetwork();
// var gameState = GD.BytesToVarWithObjects(networkData);
}
}GDScript
extends Node
func _ready():
# 第一步:准备一个包含对象引用的数据,然后打包
var _player_node = get_node("Player")
var _original_data = {
"player_ref": _player_node,
"score": 999,
"items": ["剑", "盾", "药水"]
}
# 打包成字节数组
var _packed = var_to_bytes_with_objects(_original_data)
print("打包完成,字节长度: ", _packed.size())
# 第二步:从字节数组还原
var _restored_data = bytes_to_var_with_objects(_packed)
# 验证还原结果
print("分数: ", _restored_data["score"]) # 999
print("物品: ", _restored_data["items"]) # ["剑", "盾", "药水"]
# 对象引用也还原了,指向同一个节点实例
var _restored_ref = _restored_data["player_ref"]
print("还原的节点名: ", _restored_ref.name) # Player
# 实际场景:从网络收到的字节数据还原游戏状态
# var network_data = receive_from_network()
# var game_state = bytes_to_var_with_objects(network_data)注意事项
- 此函数是
var_to_bytes_with_objects()的逆操作。用var_to_bytes_with_objects()打包的数据,必须用bytes_to_var_with_objects()来还原;用普通的var_to_bytes()打包的数据,则用bytes_to_var()来还原。两对函数不能交叉使用。 - 反序列化时,如果原始对象引用指向的节点或资源已经被销毁(不在内存中了),还原出来的引用会是
null。因此,在使用还原后的对象引用之前,建议先做空值检查。 - 如果你确定数据中不包含任何对象引用,使用普通的
bytes_to_var()会更高效。 - 此函数在多人网络游戏中特别有用:服务器可以用
var_to_bytes_with_objects()将游戏状态打包发送给客户端,客户端收到后用bytes_to_var_with_objects()还原。 - 在 C# 中,调用
GD.BytesToVarWithObjects()返回的是Variant类型,需要根据实际数据结构进行类型转换(如转换为Godot.Collections.Dictionary)。
