2025-04-06 05:48:27 +00:00
|
|
|
|
|
|
|
using Godot;
|
2025-06-12 09:03:02 +00:00
|
|
|
using System.Collections.Generic;
|
2025-04-06 05:48:27 +00:00
|
|
|
|
|
|
|
namespace Rokojori
|
|
|
|
{
|
2025-06-10 13:16:36 +00:00
|
|
|
[Tool][GlobalClass]
|
2025-04-06 05:48:27 +00:00
|
|
|
public partial class PlaySound:Action
|
|
|
|
{
|
|
|
|
[Export]
|
2025-06-12 09:03:02 +00:00
|
|
|
public AudioStreamPlayer3D player;
|
|
|
|
|
2025-07-25 15:35:19 +00:00
|
|
|
[Export]
|
|
|
|
public SelectorFlag overdrivePreventionFlag;
|
|
|
|
|
|
|
|
|
2025-07-25 08:13:35 +00:00
|
|
|
[Export]
|
|
|
|
public Duration overdrivePreventionDuration;
|
2025-06-12 09:03:02 +00:00
|
|
|
|
2025-07-25 15:35:19 +00:00
|
|
|
|
2025-06-12 09:03:02 +00:00
|
|
|
[ExportGroup("Randomize Playback Position")]
|
|
|
|
[Export]
|
|
|
|
public bool randomizePlaybackPosition = false;
|
|
|
|
|
|
|
|
[Export]
|
|
|
|
public Duration durationPerSound;
|
|
|
|
|
|
|
|
[Export]
|
2025-07-25 15:35:19 +00:00
|
|
|
public float cutBufferLengths = 0;
|
|
|
|
|
|
|
|
|
|
|
|
[Export]
|
2025-06-12 09:03:02 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
2025-04-06 05:48:27 +00:00
|
|
|
|
|
|
|
protected override void _OnTrigger()
|
|
|
|
{
|
2025-07-25 15:35:19 +00:00
|
|
|
|
|
|
|
var audioManager = Unique<AudioManager>.Get();
|
2025-07-25 08:13:35 +00:00
|
|
|
|
2025-07-25 15:35:19 +00:00
|
|
|
if ( overdrivePreventionDuration != null && overdrivePreventionFlag != null )
|
|
|
|
{
|
|
|
|
if ( ! audioManager.CanPlay( overdrivePreventionFlag, overdrivePreventionDuration.GetDurationInSeconds() ) )
|
2025-07-25 08:13:35 +00:00
|
|
|
{
|
2025-07-25 15:35:19 +00:00
|
|
|
this.LogInfo( "Can't play sound, prevention" );
|
2025-07-25 08:13:35 +00:00
|
|
|
return;
|
|
|
|
}
|
2025-07-25 15:35:19 +00:00
|
|
|
|
2025-07-25 08:13:35 +00:00
|
|
|
}
|
2025-07-25 15:35:19 +00:00
|
|
|
|
|
|
|
|
2025-07-25 08:13:35 +00:00
|
|
|
|
2025-06-12 09:03:02 +00:00
|
|
|
var offset = 0f;
|
|
|
|
|
|
|
|
var player = generatePools ? GetFreePlayer() : this.player;
|
2025-07-25 15:35:19 +00:00
|
|
|
|
|
|
|
if ( ! IsInstanceValid( player ) )
|
|
|
|
{
|
|
|
|
this.LogInfo( "Can't play sound, invalid" );
|
|
|
|
return;
|
|
|
|
}
|
2025-06-12 09:03:02 +00:00
|
|
|
|
|
|
|
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 );
|
|
|
|
|
2025-07-25 15:35:19 +00:00
|
|
|
this.LogInfo( "Play sound", offset, HierarchyName.Of( player ) );
|
|
|
|
|
|
|
|
if ( overdrivePreventionFlag != null )
|
|
|
|
{
|
|
|
|
audioManager.RecordSoundPlaying( overdrivePreventionFlag );
|
|
|
|
}
|
|
|
|
|
2025-06-12 09:03:02 +00:00
|
|
|
if ( randomizePlaybackPosition )
|
|
|
|
{
|
|
|
|
var tl = TimeLineManager.Ensure( durationPerSound.timeLine );
|
|
|
|
|
|
|
|
var start = tl.position;
|
|
|
|
|
2025-07-25 15:35:19 +00:00
|
|
|
var stopDuration = ( durationPerSound.GetDurationInSeconds() - audioManager.bufferCutLength * cutBufferLengths ) / player.PitchScale;
|
|
|
|
TimeLineManager.ScheduleSpanIn( durationPerSound.timeLine, 0, stopDuration,
|
2025-06-12 09:03:02 +00:00
|
|
|
( span, type )=>
|
|
|
|
{
|
|
|
|
var timeNow = tl.position;
|
|
|
|
var elapsed = timeNow - start;
|
|
|
|
|
|
|
|
var phase = span.phase;
|
|
|
|
|
|
|
|
if ( type == TimeLineSpanUpdateType.End )
|
|
|
|
{
|
|
|
|
player.Stop();
|
|
|
|
player.Playing = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2025-04-06 05:48:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|