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

109 lines
2.7 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@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