81 lines
2.2 KiB
GDScript
81 lines
2.2 KiB
GDScript
class_name VoicelineComponent
|
|
extends Node
|
|
|
|
@export_node_path("AudioStreamPlayer", "AudioStreamPlayer2D", "AudioListener3D")
|
|
var audio_players: Array[NodePath] = []:
|
|
set = set_audio_players
|
|
@export var voiceline_chains: Dictionary[StringName, VoicelineChain] = {}
|
|
@export var cache_voicelines: bool = false ## TODO: preload all voicelines when they need the be loaded.
|
|
|
|
var voiceline_players: Array[Node] = []
|
|
var next_voicelines: Array[VoicelineChain] = []
|
|
var current_voiceline_chain_index: int = 0
|
|
var _reference_player: Node
|
|
|
|
|
|
func set_audio_players(players: Array[NodePath]) -> void:
|
|
audio_players = players
|
|
_update_player_cache()
|
|
|
|
|
|
func push_voiceline(voiceline_chain: VoicelineChain) -> void:
|
|
next_voicelines.append(voiceline_chain)
|
|
|
|
|
|
func push_next_voiceline() -> void:
|
|
var voiceline: VoicelineChain = next_voicelines.front()
|
|
|
|
if is_instance_valid(voiceline) and current_voiceline_chain_index < voiceline.voicelines.size():
|
|
current_voiceline_chain_index += 1
|
|
_play_voiceline(voiceline.voicelines[current_voiceline_chain_index])
|
|
return
|
|
|
|
next_voicelines.remove_at(0)
|
|
voiceline = next_voicelines.front()
|
|
current_voiceline_chain_index = 0
|
|
|
|
if is_instance_valid(voiceline):
|
|
_play_voiceline(voiceline.voicelines.front())
|
|
|
|
|
|
func play_voiceline(vo_name: StringName) -> void:
|
|
if voiceline_chains.has(vo_name):
|
|
push_voiceline(voiceline_chains[vo_name])
|
|
else:
|
|
push_warning("[%s] No voiceline with the name '%s' found." % [self, vo_name])
|
|
|
|
|
|
func is_audio_player(player: Node) -> bool:
|
|
return (
|
|
is_instance_valid(player)
|
|
and (
|
|
player is AudioStreamPlayer
|
|
or player is AudioStreamPlayer2D
|
|
or player is AudioStreamPlayer3D
|
|
)
|
|
)
|
|
|
|
|
|
func _play_voiceline(voiceline_data: VoicelineData) -> void:
|
|
var voice: AudioStream = load(voiceline_data.voiceline_path)
|
|
|
|
for player: Node in voiceline_players:
|
|
player.play(voice)
|
|
|
|
|
|
func _on_voiceline_finished() -> void:
|
|
push_next_voiceline()
|
|
|
|
|
|
func _update_player_cache() -> void:
|
|
voiceline_players.clear()
|
|
|
|
for audio_player: NodePath in audio_players:
|
|
var player: Node = get_node_or_null(audio_player)
|
|
|
|
if is_audio_player(player):
|
|
voiceline_players.append(player)
|
|
_reference_player = player
|
|
|
|
_reference_player.finished.connect(_on_voiceline_finished)
|