@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 Warnings(Inspector 黄色警告) # ===================================================== 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