98 lines
2.3 KiB
C#
98 lines
2.3 KiB
C#
|
|
using Godot;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool][GlobalClass]
|
|
public partial class PlaySound:Action
|
|
{
|
|
[Export]
|
|
public AudioStreamPlayer3D player;
|
|
|
|
|
|
[ExportGroup("Randomize Playback Position")]
|
|
[Export]
|
|
public bool randomizePlaybackPosition = false;
|
|
|
|
[Export]
|
|
public Duration durationPerSound;
|
|
|
|
[Export]
|
|
public bool generatePools = true;
|
|
|
|
|
|
List<AudioStreamPlayer3D> players = new List<AudioStreamPlayer3D>();
|
|
|
|
|
|
AudioStreamPlayer3D GetFreePlayer()
|
|
{
|
|
if ( players.Count == 0 )
|
|
{
|
|
players.Add( player );
|
|
}
|
|
|
|
var freePlayer = players.Find( p => ! p.Playing );
|
|
|
|
if ( freePlayer != null )
|
|
{
|
|
return freePlayer;
|
|
}
|
|
|
|
var newPlayer = player.GetParent().CreateChild<AudioStreamPlayer3D>();
|
|
newPlayer.Stream = player.Stream;
|
|
newPlayer.VolumeDb = player.VolumeDb;
|
|
newPlayer.MaxDb = player.MaxDb;
|
|
newPlayer.UnitSize = player.UnitSize;
|
|
newPlayer.AttenuationModel = player.AttenuationModel;
|
|
|
|
players.Add( newPlayer );
|
|
return newPlayer;
|
|
|
|
}
|
|
|
|
protected override void _OnTrigger()
|
|
{
|
|
var offset = 0f;
|
|
|
|
var player = generatePools ? GetFreePlayer() : this.player;
|
|
|
|
if ( randomizePlaybackPosition )
|
|
{
|
|
var random = LCG.WithSeed( networkSeed );
|
|
|
|
var length = player.Stream.GetLength();
|
|
var numOffsets = Mathf.FloorToInt( length / durationPerSound.GetDurationInSeconds() );
|
|
var randomIndex = random.IntegerExclusive( numOffsets );
|
|
offset = randomIndex * durationPerSound.GetDurationInSeconds();
|
|
|
|
// this.LogInfo( "Offset", numOffsets, randomIndex, offset );
|
|
}
|
|
|
|
player.Play( offset );
|
|
|
|
if ( randomizePlaybackPosition )
|
|
{
|
|
var tl = TimeLineManager.Ensure( durationPerSound.timeLine );
|
|
|
|
var start = tl.position;
|
|
|
|
TimeLineManager.ScheduleSpanIn( durationPerSound.timeLine, 0, durationPerSound.GetDurationInSeconds(),
|
|
( span, type )=>
|
|
{
|
|
var timeNow = tl.position;
|
|
var elapsed = timeNow - start;
|
|
|
|
var phase = span.phase;
|
|
|
|
if ( type == TimeLineSpanUpdateType.End )
|
|
{
|
|
player.Stop();
|
|
player.Playing = false;
|
|
}
|
|
}
|
|
);
|
|
}
|
|
}
|
|
}
|
|
} |