Godot 动态获取子节点的属性导出到父节点的面板上,并可以同步修改

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

你可能感兴趣的:(Godot,GDScript)