xiandie/scene/entity/ux/player_os.gd

82 lines
2.4 KiB
GDScript3
Raw Normal View History

extends Control
signal os_finished
@onready var os_pausing_timer = %OSTimer as Timer
@onready var os_label = %OSLabel as DialogueLabel
@onready var os_contaner = %PanelContainer as PanelContainer
var os_tween: Tween
# 保证每次 pop_os 后都会有一次 os_finished 信号
var os_finish_emit_lock := Mutex.new()
var os_finished_not_emitted := false
func _ready() -> void:
if Engine.is_editor_hint():
# 显示 os 效果
os_contaner.modulate.a = 1.0
os_label.text = "os 测试文本"
return
os_contaner.modulate.a = 0.0
os_label.text = ""
os_pausing_timer.timeout.connect(_on_os_line_timeout)
func pop_os(lines := [], auto_lock := true, auto_unlock := true) -> void:
if os_tween:
os_tween.kill()
os_finish_emit_lock.lock()
if os_finished_not_emitted:
os_finished.emit()
os_finished_not_emitted = true
os_finish_emit_lock.unlock()
if auto_lock:
SceneManager.lock_player()
if auto_unlock:
# os_finished 必然发送,防止 tween 被 kill保证一定 unlock
if os_finished.is_connected(SceneManager.unlock_player):
SceneManager.unlock_player()
os_finished.connect(SceneManager.unlock_player, CONNECT_ONE_SHOT)
os_tween = create_tween()
os_label.text = ""
os_tween.tween_property(os_contaner, "modulate:a", 1.0, 0.2)
for line in lines:
# os_pausing_timer 启动最小时长 0.01 秒
var duration = max(GlobalConfigManager.config.os_wait_time, 0.01)
os_tween.tween_callback(_os_load_line.bind(line, duration))
os_tween.tween_property(os_contaner, "modulate:a", 0.0, 0.2)
os_tween.tween_callback(func():
os_finish_emit_lock.lock()
if os_finished_not_emitted:
os_finished_not_emitted = false
os_finished.emit()
os_finish_emit_lock.unlock()
)
# os 结束
await os_finished
func _os_load_line(line: DialogueLine, duration: float):
os_label.dialogue_line = line
os_label.type_out()
if os_label.finished_typing.is_connected(os_pausing_timer.start):
os_label.finished_typing.disconnect(os_pausing_timer.start)
os_label.finished_typing.connect(os_pausing_timer.start.bind(duration), CONNECT_ONE_SHOT)
os_tween.pause()
func _on_os_line_timeout(naturally := true):
if not naturally:
if os_label.is_typing:
os_label.skip_typing()
return
if os_tween.is_valid():
os_tween.play()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("interact"):
if os_pausing_timer and os_pausing_timer.time_left > 0:
get_viewport().set_input_as_handled()
_on_os_line_timeout(false)