diff --git a/Source/Editor/CustomEditors/Dedicated/AudioSourceEditor.cs b/Source/Editor/CustomEditors/Dedicated/AudioSourceEditor.cs
index 1ddc1c144..0b15773b8 100644
--- a/Source/Editor/CustomEditors/Dedicated/AudioSourceEditor.cs
+++ b/Source/Editor/CustomEditors/Dedicated/AudioSourceEditor.cs
@@ -13,6 +13,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
public class AudioSourceEditor : ActorEditor
{
private Label _infoLabel;
+ private Slider _slider;
+ private AudioSource.States _slideStartState;
///
public override void Initialize(LayoutElementsContainer layout)
@@ -28,6 +30,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
_infoLabel = playbackGroup.Label(string.Empty).Label;
_infoLabel.AutoHeight = true;
+ // Play back slider
+ var sliderElement = playbackGroup.CustomContainer();
+ _slider = sliderElement.CustomControl;
+ _slider.ThumbSize = new Float2(_slider.ThumbSize.X * 0.5f, _slider.ThumbSize.Y);
+ _slider.SlidingStart += OnSlidingStart;
+ _slider.SlidingEnd += OnSlidingEnd;
+
var grid = playbackGroup.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
@@ -40,6 +49,38 @@ namespace FlaxEditor.CustomEditors.Dedicated
}
}
+ private void OnSlidingEnd()
+ {
+ foreach (var value in Values)
+ {
+ if (value is AudioSource audioSource && audioSource.Clip)
+ {
+ switch (_slideStartState)
+ {
+ case AudioSource.States.Playing:
+ audioSource.Play();
+ break;
+ case AudioSource.States.Paused:
+ case AudioSource.States.Stopped:
+ audioSource.Pause();
+ break;
+ default: break;
+ }
+ }
+ }
+ }
+
+ private void OnSlidingStart()
+ {
+ foreach (var value in Values)
+ {
+ if (value is AudioSource audioSource && audioSource.Clip)
+ {
+ _slideStartState = audioSource.State;
+ }
+ }
+ }
+
///
public override void Refresh()
{
@@ -51,7 +92,29 @@ namespace FlaxEditor.CustomEditors.Dedicated
foreach (var value in Values)
{
if (value is AudioSource audioSource && audioSource.Clip)
+ {
text += $"Time: {audioSource.Time:##0.0}s / {audioSource.Clip.Length:##0.0}s\n";
+ _slider.Maximum = audioSource.Clip.Length;
+ _slider.Minimum = 0;
+ if (_slider.IsSliding)
+ {
+ if (audioSource.State != AudioSource.States.Playing)
+ {
+ // Play to move slider correctly
+ audioSource.Play();
+ audioSource.Time = _slider.Value;
+ }
+ else
+ {
+ audioSource.Time = _slider.Value;
+ }
+ }
+ else
+ {
+ _slider.Value = audioSource.Time;
+ }
+
+ }
}
_infoLabel.Text = text;
}
diff --git a/Source/Engine/Audio/AudioSource.cpp b/Source/Engine/Audio/AudioSource.cpp
index cff89e7e1..f16f95423 100644
--- a/Source/Engine/Audio/AudioSource.cpp
+++ b/Source/Engine/Audio/AudioSource.cpp
@@ -167,8 +167,8 @@ void AudioSource::Play()
}
else
{
- // Source was nt properly added to the Audio Backend
- LOG(Warning, "Cannot play unitialized audio source.");
+ // Source was not properly added to the Audio Backend
+ LOG(Warning, "Cannot play uninitialized audio source.");
}
}
@@ -401,6 +401,9 @@ void AudioSource::Update()
_startingToPlay = false;
}
+ if (Math::NearEqual(GetTime(), _startTime) && _isActuallyPlayingSth && _startingToPlay)
+ ClipStarted();
+
if (!UseStreaming() && Math::NearEqual(GetTime(), 0.0f) && _isActuallyPlayingSth && !_startingToPlay)
{
int32 queuedBuffers;
@@ -416,6 +419,7 @@ void AudioSource::Update()
{
Stop();
}
+ ClipFinished();
}
}
@@ -486,6 +490,7 @@ void AudioSource::Update()
{
Stop();
}
+ ClipFinished();
}
ASSERT(_streamingFirstChunk < clip->Buffers.Count());
diff --git a/Source/Engine/Audio/AudioSource.h b/Source/Engine/Audio/AudioSource.h
index b83a2b408..9858d283a 100644
--- a/Source/Engine/Audio/AudioSource.h
+++ b/Source/Engine/Audio/AudioSource.h
@@ -76,6 +76,16 @@ public:
API_FIELD(Attributes="EditorOrder(10), DefaultValue(null), EditorDisplay(\"Audio Source\")")
AssetReference Clip;
+ ///
+ /// Event fired when the audio clip starts.
+ ///
+ API_EVENT() Action ClipStarted;
+
+ ///
+ /// Event fired when the audio clip finishes.
+ ///
+ API_EVENT() Action ClipFinished;
+
///
/// Gets the velocity of the source. Determines pitch in relation to AudioListener's position. Only relevant for spatial (3D) sources.
///