Godot 3.2.3
GDScript 1.0
可以动态获取子节点的自定义的导出到面板中的变量,显示到当前的属性面板中,并可以同步修改,就是修改导出到这个节点的属性,也会修改对应子节点的这个属性
代码如下:
"""=====================================================================
PropertyList
========================================================================
[属性列表]
========================================================================
@datetime: 2020-8-7 19:00
@Godot version: 3.2.3
@author: [email protected]
@version: 1.0
====================================================================="""
tool
extends Node
class_name PropertyList
"""私有变量"""
var _custom_property_list : Array = []
##==============================
## 内置方法
##==============================
func _set(property: String, value) -> bool:
# 修改属性时,将对应子节点的值也修改
for custom_property in _custom_property_list:
if custom_property['name'] == property:
# 转换 NodePath 类型节点跟子节点匹配
if custom_property['type'] == TYPE_NODE_PATH:
if value != '':
var tmp_node = get_node_or_null(value)
if tmp_node != null:
value = custom_property['host'].get_path_to(tmp_node)
# 修改子节点的属性
custom_property['host'].set(custom_property['origin_name'], value)
return true
func _get(property: String):
# 获取对应子节点的属性值
for custom_property in _custom_property_list:
if custom_property['name'] == property && custom_property.has('host'):
var property_value = custom_property['host'].get(custom_property['origin_name'])
if custom_property['type'] == TYPE_NODE_PATH:
property_value = self.get_path_to(custom_property['host'].get_node_or_null(property_value))
return property_value
return true
func _get_property_list() -> Array:
# 更新属性列表
update_custom_property_list()
# 设置自定义属性,更新到属性面板中
return _custom_property_list
func _enter_tree() -> void:
update_custom_property_list()
##==============================
## 自定义方法
##==============================
func update_custom_property_list() -> void:
"""更新自定义属性列表"""
_custom_property_list = []
# 属性栏面板显示方式
# _custom_property_list.append({
# name='Property List',
# type=TYPE_NIL,
# usage=PROPERTY_USAGE_DEFAULT_INTL | PROPERTY_USAGE_CATEGORY
# })
# 遍历搜索 PropertyBase 类节点
for property_node in get_children():
if property_node is PropertyBase: # 这一行if可以去掉,这个主要是判断对应的节点而写的,自己用的话可以去掉
# 添加 [属性节点的属性] 到 [自身自定义的属性]
append_custom_property_list(property_node)
func append_custom_property_list(property_node) -> void:
"""添加自定义属性
@property_node: 属性节点
"""
# 添加属性
for property_data in get_custom_property_list(property_node):
# 记录这个属性的 [host]
property_data['host'] = property_node
property_data['origin_name'] = property_data['name']
property_data['name'] = property_node.name + '/' + property_data['name']
# 将 “属性节点” 的 “自定义属性” 添加到当前的 “_custom_property_list” 中
_custom_property_list.append(property_data)
# ==================== 注意事项 =======================
# get_custom_property_list 和 is_custom_property 这两个
# 函数在这个脚本里是必须要有的,否则动态属性列表将不起作用
# ===================================================
func get_custom_property_list(obj: Object) -> Array:
"""获取节点的自定义属性列表"""
var property_list : Array = []
for i in obj.get_property_list():
# 这是一个 [自定义] 的属性 [usage] 则添加
if is_custom_property(i['usage']):
property_list.append(i)
return property_list
func is_custom_property(var_usage) -> bool:
"""返回变量是否是自定义属性
@var_usage 变量标识
"""
if (var_usage == PROPERTY_USAGE_SCRIPT_VARIABLE ||
var_usage == PROPERTY_USAGE_SCRIPT_VARIABLE | PROPERTY_USAGE_STORAGE
| PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK
):
return true
return false