/// <summary> /// Play Sfx audio track. /// </summary> /// <param name="audio">Audio clip and settings SO</param> /// <param name="followTarget">Target for the sfx to follow when playing.</param> public CancellationTokenSource Play(ISfxAudio audio, Transform followTarget = null) { PoolTracker = PoolTracker ?? new SfxPoolTracker(PoolSize); try { // set transform parent if (followTarget == null) { followTarget = Mic.Transform; } // borrow sfx from pool SfxPlayComponent sfxPlayComponent = PoolTracker.Borrow(audio, followTarget); if (sfxPlayComponent == null) { return(null); } // play sfx and return cancellation token source return(sfxPlayComponent.Play(audio, audioMixerGroup, followTarget)); } catch (ErrPoolExhausted) { Debug.Log("Pool is full and audio is low priority. Skipping..."); return(null); } }
/// <summary> /// Update all active SFX instances. /// </summary> /// <param name="ct">Cancellation token to stop update</param> async UniTask UpdateInstancesAsync() { while (true) { await Delay.NextFrame(); for (int i = activeSfx.Count - 1; i >= 0; i--) { SfxPlayComponent sfx = activeSfx[i]; if (sfx.AudioSource == null) { continue; } // stopped if (!sfx.AudioSource.isPlaying) { Return(sfx); } // canceled else if (sfx.Ct.IsCancellationRequested || sfx.FollowTarget == null) { Stop(sfx); } // playing else { // update position sfx.AudioSource.transform.position = sfx.FollowTarget.position; } } lowestPrioritySfx = FindLowestSfxRank(); } }
/// <summary> /// Borrow SFX play instance. /// </summary> public SfxPlayComponent Borrow(ISfxAudio audio, Transform followTarget) { if (pool.ItemsAvailable == 0) { // obtain ranks of the requested sfx and compare it with the lowest ranked sfx. int rank = audio.Priority.GetRank(followTarget); int lowestRank = lowestPrioritySfx.GetRank(); // don't play sfx if it has the lowest rank. if (rank == lowestRank) { return(null); } // stop lowest priority sfx and return it to pool. Stop(lowestPrioritySfx); } try { SfxPlayComponent sfx = pool.Borrow(); activeSfx.Add(sfx); return(sfx); } catch (ErrPoolExhausted e) { Debug.LogError(e.Message); return(null); } }
void Return(SfxPlayComponent sfx) { sfx.AudioSource.clip = null; pool.Return(sfx); activeSfx.Remove(sfx); lowestPrioritySfx = FindLowestSfxRank(); }
void Stop(SfxPlayComponent sfx) { sfx.AudioSource.Stop(); Return(sfx); }