Godot 4.1.1动态属性GUI菜单:可编辑字段实现方案问询
解决方案:Godot动态可编辑属性GUI实现自动更新
核心思路是将目标对象和属性名直接传递给信号回调函数,让GUI控件的变化能精准映射回原对象的属性。以下是具体实现步骤和代码修改:
1. 改造可编辑属性创建函数
新增参数接收目标对象和对应属性名,同时可根据属性类型添加输入过滤,避免无效输入:
func _add_editable_property(name: String, initial_value: String, target_object: Object, property_name: String): var label = Label.new() label.text = name label.size_flags_horizontal = Control.SIZE_EXPAND_FILL var value_input = LineEdit.new() value_input.text = initial_value # 可选:根据属性类型设置输入过滤,限制输入格式 var prop_info_idx = target_object.get_property_list().find(func(info): return info.name == property_name) if prop_info_idx != -1: match target_object.get_property_list()[prop_info_idx].type: TYPE_INT: value_input.input_filter = LineEdit.FILTER_INT TYPE_FLOAT: value_input.input_filter = LineEdit.FILTER_FLOAT # 其他类型如布尔值可自定义过滤规则 properties_grid_container.add_child(label) properties_grid_container.add_child(value_input) # 连接信号,传递目标对象和属性名作为额外参数 # 实时更新用text_changed,提交时更新用text_submitted,按需选择 value_input.connect("text_changed", self, "_on_property_changed", [target_object, property_name]) # value_input.connect("text_submitted", self, "_on_property_changed", [target_object, property_name])
2. 实现属性更新回调函数
根据属性类型自动转换输入值,再赋值给目标对象:
func _on_property_changed(new_text: String, target_object: Object, property_name: String): var prop_info_idx = target_object.get_property_list().find(func(info): return info.name == property_name) if prop_info_idx == -1: return # 属性不存在,直接终止 var prop_type = target_object.get_property_list()[prop_info_idx].type # 按属性类型转换输入值 var converted_value = match prop_type: TYPE_INT: if new_text.empty(): 0 else: int(new_text) TYPE_FLOAT: if new_text.empty(): 0.0 else: float(new_text) TYPE_STRING: new_text TYPE_BOOL: new_text.to_bool() # 支持"true"/"false"或"1"/"0"格式 # 扩展:Vector2/Color等类型可添加对应解析逻辑,比如Vector2.from_string(new_text) _: new_text # 默认按字符串处理 # 给目标对象的属性赋值 target_object.set(property_name, converted_value)
3. 修改选中对象时的属性调用逻辑
在_on_grouped中调用改造后的函数,传入目标对象和属性名:
func _on_grouped(group: String, node: Node): if group == "selected": properties_open = true # 清除旧控件 for child in properties_grid_container.get_children(): properties_grid_container.remove_child(child) child.queue_free() if node.parent_object is TypeOne: var my_object = node.parent_object _add_editable_property("ID", str(my_object.custom_id), my_object, "custom_id") if node.parent_object is TypeTwo: var my_object = node.parent_object _add_editable_property("Property Two", str(my_object.custom_property_two), my_object, "custom_property_two")
关键注意事项
- 信号选择:
text_changed会实时响应每一次输入,适合即时反馈场景;text_submitted仅在回车或失去焦点时触发,避免输入过程中频繁更新。 - 错误处理:可添加
try-except块捕获转换失败的情况(比如非数字输入到整数字段),添加提示或回退到原值。 - 属性权限:确保目标对象的属性是可写的(非只读),否则
set方法会失效。
内容的提问来源于stack exchange,提问作者AdmiralJonB
相关产品推荐
相关产品推荐

