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

89 lines
2.0 KiB
GDScript

@tool
@icon("res://addons/reedscene/prop/icon/prop_states_manager.svg")
class_name ReedPropStateManager
extends Node
@export var auto_refresh: bool = true
func _ready() -> void:
if not Engine.is_editor_hint():
return
child_entered_tree.connect(_on_child_entered_tree)
child_exiting_tree.connect(_on_child_exiting_tree)
_refresh_states()
func _notification(what: int) -> void:
if not Engine.is_editor_hint():
return
if what == NOTIFICATION_CHILD_ORDER_CHANGED:
if auto_refresh:
call_deferred("_refresh_states")
func _on_child_entered_tree(node: Node) -> void:
if not Engine.is_editor_hint():
return
if node is ReedPropState and auto_refresh:
call_deferred("_refresh_states")
func _on_child_exiting_tree(node: Node) -> void:
if not Engine.is_editor_hint():
return
if node is ReedPropState and auto_refresh:
call_deferred("_refresh_states")
func _refresh_states() -> void:
var index := 0
for child in get_children():
if not child is ReedPropState:
continue
_assign_state_id(child, index)
_rename_state_node(child, index)
index += 1
func _assign_state_id(state: ReedPropState, id: int) -> void:
if state.state_id == id:
return
state.set("state_id", id)
func _rename_state_node(state: ReedPropState, id: int) -> void:
var base_name := _strip_id_prefix(state.name)
var expected := "[ID_%d] %s" % [id, base_name]
if state.name == expected:
return
state.name = expected
func _strip_id_prefix(name: String) -> String:
var result := name
# 连续剥离所有 [ID_x] 前缀,防止叠加
while result.begins_with("[ID_"):
var end := result.find("]")
if end == -1:
break
# 跳过 "] " 或 "]"
var cut := end + 1
if cut < result.length() and result[cut] == " ":
cut += 1
result = result.substr(cut)
return result.strip_edges()
func _extract_raw_name(name: String) -> String:
if name.begins_with("[ID:"):
var end := name.find("]")
if end != -1 and end + 2 < name.length():
return name.substr(end + 2)
return name