92 lines
2.5 KiB
GDScript
92 lines
2.5 KiB
GDScript
class_name DialogPlayer
|
|
extends Node
|
|
|
|
signal dialog_finished(dialog_key: StringName)
|
|
|
|
static var active_dialog_playbacks: Array[DialogEntryPlayback] = []
|
|
|
|
@export_node_path("AudioStreamPlayer", "AudioStreamPlayer2D", "AudioStreamPlayer3D")
|
|
var audio_player: NodePath: set = set_audio_player
|
|
|
|
@export var dialogs: Dictionary[StringName, DialogEntry] = {}
|
|
|
|
var _audio_player: Node
|
|
var _current_dialog_key: StringName
|
|
var _current_dialog_playback: DialogEntryPlayback
|
|
|
|
|
|
func _ready() -> void:
|
|
set_process(false)
|
|
set_audio_player(audio_player)
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
if is_instance_valid(_audio_player) and is_instance_valid(_current_dialog_playback):
|
|
_current_dialog_playback.playback_position = _audio_player.get_playback_position()
|
|
|
|
|
|
func set_audio_player(audio_player_path: NodePath) -> void:
|
|
if is_instance_valid(_audio_player):
|
|
_audio_player.finished.disconnect(_on_dialog_finished)
|
|
|
|
audio_player = audio_player_path
|
|
_audio_player = get_node_or_null(audio_player)
|
|
|
|
if not is_instance_valid(_audio_player):
|
|
set_process(false)
|
|
return
|
|
|
|
if (
|
|
not _audio_player.has_method(&"play")
|
|
or not _audio_player.has_method(&"get_playback_position")
|
|
or not &"playing" in _audio_player
|
|
or not _audio_player.has_signal(&"finished")
|
|
):
|
|
_audio_player = null
|
|
push_error("audio_player is not a valid player.")
|
|
return
|
|
|
|
set_process(_audio_player.playing)
|
|
|
|
if not _audio_player.finished.is_connected(_on_dialog_finished):
|
|
_audio_player.finished.connect(_on_dialog_finished)
|
|
|
|
|
|
func play(entry_key: StringName, from_position: float = 0.0) -> void:
|
|
var dialog_entry: DialogEntry = dialogs.get(entry_key)
|
|
|
|
if is_instance_valid(dialog_entry):
|
|
stop_dialog()
|
|
|
|
_audio_player.stream = dialog_entry.get_voiceline_stream()
|
|
_current_dialog_key = entry_key
|
|
_current_dialog_playback = DialogEntryPlayback.new(dialog_entry)
|
|
active_dialog_playbacks.append(_current_dialog_playback)
|
|
|
|
_audio_player.play(from_position)
|
|
set_process(true)
|
|
|
|
|
|
func get_current_dialog_entry() -> DialogEntry:
|
|
return dialogs.get(_current_dialog_key)
|
|
|
|
|
|
func get_playback_position() -> float:
|
|
return _audio_player.get_playback_position() if is_instance_valid(_audio_player) else 0.0
|
|
|
|
|
|
func stop_dialog() -> void:
|
|
active_dialog_playbacks.erase(_current_dialog_playback)
|
|
_current_dialog_key = &""
|
|
_current_dialog_playback = null
|
|
_audio_player.stream = null
|
|
|
|
|
|
func _on_dialog_finished() -> void:
|
|
var entry: DialogEntry = dialogs.get(_current_dialog_key)
|
|
|
|
stop_dialog()
|
|
set_process(false)
|
|
|
|
dialog_finished.emit(entry)
|