如何在GDExtension中自动将脚本设为Singleton(Autoload)
在GDExtension中自动注册Singleton(无需编辑器手动配置)
可以实现,核心是通过GDExtension的初始化逻辑结合Godot的API完成自动配置,以下是两种可行方案:
方案1:自动修改项目配置(持久化)
通过操作ProjectSettings在初始化时添加Autoload条目,修改会保存到project.godot,重启编辑器依然生效:
#include <godot_cpp/core/class_db.hpp> #include <godot_cpp/classes/project_settings.hpp> #include <godot_cpp/classes/engine.hpp> using namespace godot; void gdextension_init(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } // 仅在编辑器模式下执行(对应GDScript的@tool) if (Engine::get_singleton()->is_editor_hint()) { Ref<ProjectSettings> proj_settings = ProjectSettings::get_singleton(); const String autoload_class = "GDExample"; // 你的GDExtension注册类名 const String autoload_name = "GDExampleSingleton"; // 避免重复添加Autoload条目 if (!proj_settings->has_setting("autoload/" + autoload_name)) { proj_settings->set_setting("autoload/" + autoload_name, autoload_class); proj_settings->save(); // 保存到project.godot } } ClassDB::register_class<GDExample>(); }
- 注意:若你的类需要指定资源路径,可将
autoload_class替换为对应的.gdextension或类文件路径 - 该方案会修改项目配置文件,适合需要长期生效的场景
方案2:编辑器会话内临时注册(非持久化)
通过编写EditorPlugin动态实例化类并注册为全局单例,不会修改项目文件,仅当前编辑器会话有效:
#include <godot_cpp/classes/editor_plugin.hpp> #include <godot_cpp/classes/engine.hpp> #include "gdexample.h" using namespace godot; class MyExtensionEditorPlugin : public EditorPlugin { GDCLASS(MyExtensionEditorPlugin, EditorPlugin); protected: static void _bind_methods() {} public: void _enter_tree() override { // 实例化GDExtension类 GDExample* singleton = memnew(GDExample); // 注册为全局单例 Engine::get_singleton()->register_singleton("GDExampleSingleton", singleton); // 添加到插件节点树,确保编辑器退出时自动清理 add_child(singleton); } void _exit_tree() override { // 注销单例 Engine::get_singleton()->unregister_singleton("GDExampleSingleton"); } }; // 在gdextension_init中注册编辑器插件 void gdextension_init(ModuleInitializationLevel p_level) { if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) { ClassDB::register_class<MyExtensionEditorPlugin>(); EditorPlugin::add_plugin(MyExtensionEditorPlugin::get_class_static()); } if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { ClassDB::register_class<GDExample>(); } }
- 该方案完全不修改项目配置,适合作为插件提供的临时全局服务
内容的提问来源于stack exchange,提问作者Manas R. Makde
相关产品推荐
相关产品推荐

