Godot 3.3.2
动态的属性列表
先看效果(注意右边的属性面板):
代码如下:
tool
extends Node2D
# 在这里添加数据
const PROPERTY_LIST = {
# Key = [属性名, 属性类型, 提示, 提示字符串]
Script = ["Script", TYPE_OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "GDScript"],
}
var property_count = 0 setget set_property_count
## 面板属性列表
var __property_list = []
## 自定义属性修改的数据
var __property_data = {}
##==================================================
# Set/Get
##==================================================
func set_property_count(value):
# property_count 值跟上次相差多少
var diff = value - property_count
# 超过上次的值,则增加属性
if diff > 0:
for i in diff:
add_property()
# 比上次的小,则减少属性
elif diff < 0:
for i in abs(diff * PROPERTY_LIST.size()):
remove_property()
property_count = value
# 更新属性面板
property_list_changed_notify()
##==================================================
# 内置方法
##==================================================
func _get_property_list():
# 属性列表
var p_list = []
# 属性类别
p_list.append({
name = "Script List",
type = TYPE_NIL,
usage = PROPERTY_USAGE_CATEGORY,
})
# 属性:脚本数量
p_list.append(_format_data("property_count", TYPE_INT, PROPERTY_HINT_RANGE, "0, 10, 1, or_greater"))
# 属性:脚本列表
p_list.append({
name="_list",
type = TYPE_NIL,
usage = PROPERTY_USAGE_GROUP,
})
p_list.append_array(__property_list)
return p_list
func _set(property, value):
# 记录属性数据
__property_data[property] = value
func _get(property):
# 返回属性数据
if __property_data.has(property):
return __property_data[property]
##==================================================
# 自定义方法
##==================================================
## 格式化数据
## @property 属性名
## @type 类型
## @hint 标识类型
## @hint_string 标识字符串
## @return 返回格式化后的数据
func _format_data(
property: String,
type: int,
hint := PROPERTY_HINT_NONE,
hint_string :=""
) -> Dictionary:
return {
name = property,
type = type,
hint = hint,
hint_string = hint_string,
}
## 添加一个属性
func add_property() -> void:
# 根据 PROPERTY_LIST 中的数据添加属性
var idx = 0
for key in PROPERTY_LIST:
idx = __property_list.size()
var property = PROPERTY_LIST[key]
__property_list.push_back(
_format_data(
property[0] + "_" + str(idx),
property[1], property[2], property[3]
)
)
## 移除一个属性
func remove_property() -> void:
# 移除掉最末尾的属性
var idx = __property_list.size() - 1
__property_list.remove(idx);
如果我们想获取这个节点的这个属性,比如这个节点的名字为 Node,则可以进行如下操作
func _ready():
var n = $Node
var s = n.get(script_0) as GDScript # 获取节点的这个属性
if s:
s.reload() # 加载这个脚本,如果不加载的话,这个脚本只是一个 Resource 类型的文件,没有功能
print(s.new()) # 创建一个新的这个脚本对象实例
注意:使用 tool 关键字后,修改完代码脚本不会立即生效,需要切换到别的场景再切换回来,或者关闭场景重新打开,才能生效。