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