You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用GDExtension和C++为Godot自定义节点实现可正常工作的工具按钮?

如何使用GDExtension和C++为Godot自定义节点实现可正常工作的工具按钮?

看起来你已经走对了大部分流程——编译通过、按钮也显示出来了,但点击按钮的问题出在工具按钮的方法绑定逻辑上。我来帮你理清问题所在并给出修复方案。

问题根源分析

你当前的代码有两个核心问题:

  1. 你的generateWorld方法返回了一个Callable对象,但编辑器的工具按钮需要的是可以直接执行的无参数/无返回值方法,而不是返回可调用对象的方法。
  2. 你在ADD_PROPERTY里用了Variant::CALLABLE类型的PropertyInfo,但工具按钮本质上不是一个需要存储值的属性,这个类型设置完全不符合工具按钮的设计逻辑,这也是导致崩溃或报错的直接原因。

修复方案(两种可选方式)

方式一:修正原有ADD_PROPERTY的用法

我们把方法改成直接执行逻辑的形式,调整属性绑定的参数:

1. 修改头文件voxel_chunk.h

把返回CallablegenerateWorld改成无返回值的方法:

#pragma once

#include <godot_cpp/classes/node3d.hpp>

namespace godot { 
    class VoxelChunk : public Node3D{
        GDCLASS(VoxelChunk, Node3D)

        private:
            void _generateWorld();

        protected:
            static void _bind_methods();
        
        public:
            void generateWorld(); // 这里改成void返回类型
            VoxelChunk();
            ~VoxelChunk();
    };
}
2. 修改实现文件voxel_chunk.cpp

调整generateWorld的实现,让它直接触发私有逻辑,并修正绑定代码:

#include "voxel_chunk.h"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/classes/utility_functions.hpp>

using namespace godot;

VoxelChunk::VoxelChunk() {
}

VoxelChunk::~VoxelChunk()
{
}

void VoxelChunk::_generateWorld()
{
    UtilityFunctions::print("Generated");
}

// 直接调用私有逻辑,不再返回Callable
void VoxelChunk::generateWorld(){
    _generateWorld();
}

void VoxelChunk::_bind_methods() {
    ClassDB::bind_method(D_METHOD("generateWorld"), &VoxelChunk::generateWorld);

    // 修正PropertyInfo:用NIL类型,因为工具按钮不需要存储属性值
    ADD_PROPERTY(
        PropertyInfo(
            Variant::NIL, 
            "", 
            PROPERTY_HINT_TOOL_BUTTON, 
            "Generate Chunk", 
            PROPERTY_USAGE_EDITOR
        ), 
        "", 
        "generateWorld"
    );
}

方式二:更直观的ADD_TOOL_BUTTON_ITEM

如果你觉得用ADD_PROPERTY做工具按钮有点绕,Godot提供了专门的宏ADD_TOOL_BUTTON_ITEM,写法更清晰:
只需要把_bind_methods里的ADD_PROPERTY替换成以下代码:

void VoxelChunk::_bind_methods() {
    ClassDB::bind_method(D_METHOD("generateWorld"), &VoxelChunk::generateWorld);
    // 直接添加工具按钮:参数1是按钮文本,参数2是要调用的方法名
    ADD_TOOL_BUTTON_ITEM("Generate Chunk", "generateWorld");
}

这种方式不需要写复杂的PropertyInfo,逻辑更直接。

验证效果

修改后重新编译GDExtension,把自定义节点加到场景里,点击"Generate Chunk"按钮,你就能在控制台看到"Generated"的输出了,不会再出现崩溃或报错。

关键注意事项

  • 工具按钮触发的方法必须是无参数、无返回值的(如果有参数必须带默认值,但工具按钮场景下一般用无参数的)。
  • 不要给工具按钮绑定返回Callable的方法,编辑器期望的是直接执行的逻辑方法,不是返回可调用对象的方法。
  • 所有要暴露给编辑器的方法,必须通过ClassDB::bind_method正确注册,否则编辑器找不到对应的方法。

火山引擎 最新活动