You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot脚本问题:如何识别运行时被点击的按钮

解决Godot动态生成按钮的点击识别问题

针对你遇到的动态按钮点击无法识别的问题,这里提供几种实用的解决方案:

方案一:信号连接时绑定参数(推荐)

在创建按钮时,直接将对应角色的索引或文件名绑定到点击信号的回调函数中,点击时就能直接拿到关联数据:

修改populate函数中的信号连接代码,同时调整export函数接收参数:

# 修改populate函数的循环部分
for i in range(characters):
    var but = Button.new()
    add_child(but)
    # 绑定当前索引i到export函数
    but.pressed.connect(funcref(self, "export").bind(i))
    but.set_position(Vector2(x,y))
    but.set_button_icon(texture)
    x += 250
    if x > 1250:
        x = 100
        y += 250
    array.push_back(but)

# 修改export函数接收参数
func export(index):
    # 通过索引获取对应的角色文件名
    var character_name = files[index]
    print("点击了角色:", character_name)
    # 这里可以添加后续逻辑,比如加载对应角色资源
    var path = "res://Characters/" + character_name + "/" + character_name + ".gd"
    var char = load(path)
    var dic = char.import()

方案二:通过按钮实例匹配数组索引

如果需要通过instance_id来匹配,可以在点击时获取发出信号的按钮实例,再遍历数组找到对应的索引:

# 修改export函数
func export():
    # 获取当前点击的按钮实例
    var clicked_button = get_tree().get_current_signal_emitter()
    # 遍历数组找到对应的索引
    for index in range(array.size()):
        if array[index].get_instance_id() == clicked_button.get_instance_id():
            var character_name = files[index]
            print("点击了角色:", character_name)
            break

方案三:给按钮添加自定义元数据

给每个按钮设置自定义元数据存储角色信息,点击时直接读取:

# 修改populate函数的循环部分
for i in range(characters):
    var but = Button.new()
    add_child(but)
    but.pressed.connect(self.export)
    # 设置自定义元数据,存储角色文件名
    but.set_meta("character_name", files[i])
    but.set_position(Vector2(x,y))
    but.set_button_icon(texture)
    x += 250
    if x > 1250:
        x = 100
        y += 250
    array.push_back(but)

# 修改export函数
func export():
    var clicked_button = get_tree().get_current_signal_emitter()
    var character_name = clicked_button.get_meta("character_name")
    print("点击了角色:", character_name)

额外优化建议

  • 你的scan_directory函数会把目录下的所有文件/文件夹都加入files,建议过滤掉隐藏文件或无效项:
func scan_directory():
    var dir = DirAccess.open("res://Characters/")
    dir.list_dir_begin()
    var current = dir.get_next()
    while current != "":
        # 跳过隐藏文件和非文件夹(假设每个角色对应一个文件夹)
        if not current.begins_with(".") and dir.current_is_dir():
            files.push_back(current)
        current = dir.get_next()
    characters = files.size()
  • populate函数中可以直接遍历files数组,不用依赖characters变量,逻辑更清晰:
func populate():
    var x = 100
    var y = 100
    var texture = load("res://img/button.jpg")

    for character_name in files:
        var but = Button.new()
        add_child(but)
        but.pressed.connect(funcref(self, "export").bind(character_name))
        but.set_position(Vector2(x,y))
        but.set_button_icon(texture)
        x += 250
        if x > 1250:
            x = 100
            y += 250
        array.push_back(but)

内容的提问来源于stack exchange,提问作者Stwest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 06:10:45