Variant(core/variant/variant.h)是 Godot 的动态类型容器:脚本语言、序列化、属性系统、方法调用全部通过它传递值。设计目标:小对象零分配、大对象引用计数、调用分发接近原生速度。

类型枚举

Type 枚举(variant.h:97-147)共 39 类 + VARIANT_MAX 哨兵:

分组类型数量
空NIL1
原子BOOL / INT / FLOAT / STRING4
数学VECTOR2, VECTOR2I, RECT2, RECT2I, VECTOR3, VECTOR3I, TRANSFORM2D, VECTOR4, VECTOR4I, PLANE, QUATERNION, AABB, BASIS, TRANSFORM3D, PROJECTION15
杂项COLOR, STRING_NAME, NODE_PATH, RID, OBJECT, CALLABLE, SIGNAL, DICTIONARY, ARRAY9
打包数组PACKED_BYTE_ARRAY … PACKED_VECTOR4_ARRAY10

存储布局

Type type + union _data(variant.h:163-267):

  • 小对象内联:_mem[] 大小取 sizeof(ObjData) 与 4*real_t 较大者;float 构建下 Variant 共 24 字节
  • 大对象堆分配:_transform2d/_aabb/_basis/_transform3d/_projection 经指针字段持有
  • Packed 数组:引用计数的 PackedArrayRef(variant.h:194-249),多 Variant 共享底层缓冲
  • OBJECT:内联 ObjData{ObjectID id; Object *obj}(variant.h:174-191);对 RefCounted 子类自动 ref/unref;needs_deinit 表(:273-317)控制哪些类型需要析构

对象经 ObjectID 验活:debug 下从 Variant 取 Object 指针前用 ObjectDB::get_instance 校验,防止悬挂指针(与 object-model 的 ObjectDB 呼应)。

调用分发

Variant::call()(variant_call.cpp:1391-1420):

  • OBJECT 类型 → obj->callp()(debugger 激活时用 ObjectDB 验活)
  • 内建类型 → 查每类型 builtin_method_info[type] 表(VariantBuiltMethodInfo{call, validated_call, ptrcall, ...});_VariantCall 结构体(:669)在 _register_variant_methods 中注册全部内建方法

三档调用路径与 MethodBind 一致:动态 call(带 CallError)、validated_call、ptrcall。GDScript VM 对已知签名的调用走 validated 路径以跳过 Variant 装箱,见 gdscript。

与脚本/序列化的关系

  • 属性系统:Object::get/set 的出入口都是 Variant,见 object-model
  • 场景序列化:SceneState 的属性值池就是 Variant 列表,见 scene-tree
  • Callable/SIGNAL 是一等 Variant 类型,支撑信号连接的脚本侧表达
  • GDExtension ABI 全部基于 Variant(或 ptrcall 的原生指针)

相关