dasasdhba 发表于 2026-5-23 01:36:53

dasasdhba 发表于 2025-5-9 23:28
24. 调试模式下,Notification + InternalProcess 比 _process 快得多

本条仅针对 C#,详见:https://gith ...

29. C# 的 GD virtual call

最近几天看了一下原理,大致说一下。Godot 的 C# 检查一个 GD virtual 函数是否有被 override,基本上是靠一个参数为 StringName 的 virtual 的递归函数,这个函数将返回一个脚本函数是否被 override。以检查 _process 是否有被 override 为例,godot 引擎首先将 "_process" 传入了这个函数,然后这个函数又递归地将 "_Process" 传入自己。然后,godot 的 source generator 会在 _Process 函数确实被 override 了的时候,去自动地 override 之前提到的递归的虚函数,使得输入 "_Process" 会返回 true。

且不说这些查询全用的是 if,我很好奇为什么不选择直接建立一个 FrozenDictionay 来存储返回值;最起码引擎 cpp 层也可以做一次缓存,这些 if 查询运行时肯定都是不变的,缓存一下也就只会执行一次,还算可以接受;这些缓存无非是拿一些内存和启动时间来换速度,说实话游戏我还是觉得要以性能为主,这个 trade 完全值得。最后递归调自己的操作我是真没看懂,分成两个函数不行么,那些递归调自己的都是引擎层的 binding,你source generator去把用户数据生成到另一个函数不好么,虚函数递归那vtable查询能不慢么?总之我完全没搞懂 godot 这么搞是何意,这不纯浪费性能么?

总结来说,对于大型 C# 项目,如果大量的 _Process 成为性能瓶颈,要么自己手动管理这些 Process,少走 godot 的这套 virtual call,要么就把这个 binding 逻辑改了,加上缓存真不是什么难事。

dasasdhba 发表于 2026-6-2 10:44:10

本帖最后由 dasasdhba 于 2026-6-2 11:11 编辑

30. 对于 C#,运行时给 GodotObject 附带数据不必使用 Godot 的 metadata 系统,这套系统是 Variant Dictionary,设计给编辑器用的,很慢。事实上,.NET 生态自带 ConditionalWeakTable 类,天然适合干这个事情。当然,如果你希望运行时 PackedScene.Pack 能打包这些附带数据,那只能用 metadata。
页: 1 [2]
查看完整版本: 【随缘更新】Godot 小知识