Godot dynamically obtains the attributes of child nodes and exports them to the panel of the parent node, and can be modified synchronously

Godot 3.2.3
GDScript 1.0

You can dynamically obtain the custom variables exported to the panel of the child node, display it in the current attribute panel, and can be modified synchronously, that is, modify the attribute exported to this node, and also modify the attribute of the corresponding child node

code show as below:

"""=====================================================================
				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

Guess you like

Origin blog.csdn.net/qq_37280924/article/details/107942433