godot-plateformer/addons/reedscene/prop/PropManager.gd

109 lines
2.7 KiB
GDScript3
Raw Normal View History

2025-12-31 13:07:31 +08:00
@tool
extends Node2D
##是否要自动的向其子集中添加一个PropComp
@export var auto_attach_prop_component := true
##是否要输出Debug Message
@export var debug_log := true
##输出一个ID的前缀方便策划调整
const PREFIX := "[Prop_%04d]"
func _ready() -> void:
if not Engine.is_editor_hint():
return
_ensure_existing_props()
child_entered_tree.connect(_on_child_entered_tree)
# 强制让 Editor 重新计算 configuration warnings
update_configuration_warnings()
func _on_child_entered_tree(node: Node) -> void:
if not Engine.is_editor_hint():
return
_try_attach_and_assign(node)
# 子节点变化后,刷新 Inspector 警告
update_configuration_warnings()
func _ensure_existing_props() -> void:
for child in get_children():
_try_attach_and_assign(child)
func _try_attach_and_assign(prop: Node) -> void:
if not auto_attach_prop_component:
return
if prop == null:
return
if prop is PropComponent:
return
var comp := _find_prop_component_top(prop)
if comp == null:
comp = PropComponent.new()
comp.name = "PropComponent" # 临时名
prop.add_child(comp)
comp.owner = get_tree().edited_scene_root
# 确保 prop_id 唯一且有效
if int(comp.prop_id) < 0 or _is_prop_id_used_elsewhere(int(comp.prop_id), comp):
comp.prop_id = _alloc_prop_id()
# 用 prop_id 重命名 PropComponent
comp.name = PREFIX % int(comp.prop_id)
if debug_log:
print("[PropManager][Editor] Ensure PropComponent:", prop.name, "->", comp.name, "id=", comp.prop_id)
func _find_prop_component_top(prop: Node) -> PropComponent:
for child in prop.get_children():
if child is PropComponent:
return child as PropComponent
return null
func _alloc_prop_id() -> int:
var max_id := -1
for prop in get_children():
var comp := _find_prop_component_top(prop)
if comp == null:
continue
max_id = maxi(max_id, int(comp.prop_id))
return max_id + 1
func _is_prop_id_used_elsewhere(prop_id: int, self_comp: PropComponent) -> bool:
for prop in get_children():
var comp := _find_prop_component_top(prop)
if comp == null:
continue
if comp == self_comp:
continue
if int(comp.prop_id) == prop_id:
return true
return false
# =====================================================
# Editor Configuration WarningsInspector 黄色警告)
# =====================================================
func _get_configuration_warnings() -> PackedStringArray:
var warnings := PackedStringArray()
if not Engine.is_editor_hint():
return warnings
for prop in get_children():
if prop is PropComponent:
continue
var comp := _find_prop_component_top(prop)
if comp == null:
warnings.append(
"Prop '%s' has no PropComponent as a top-level child." % prop.name
)
return warnings