/// <summary> /// Repeatedly trigger the one-off container based on the loop time. /// </summary> private IEnumerator PlayLoopingOneOffContainerCoroutine(ActiveEvent activeEvent) { int?currentIndex = null; while (!activeEvent.StopRequested) { UPlayable currentPlayable = null; if (!this.IsSimultaneous) { currentIndex = this.GenerateNextClipIndex(currentIndex); currentPlayable = this.sounds[currentIndex.Value]; } // Start coroutine (don't yield return) so that the wait time is accurate, since length includes delay. StartCoroutine(PlayOneOffContainerCoroutine(activeEvent, currentPlayable)); float eventLoopTime = loopTime; // Protect against containers looping every frame by defaulting to the length of the audio clip. if (eventLoopTime == 0) { if (!this.IsSimultaneous) { eventLoopTime = currentPlayable.GetLength(); } else { eventLoopTime = this.GetLength(); } } yield return(new WaitForSeconds(eventLoopTime)); } }
private IEnumerator PlayClipCoroutine(UPlayable playable, ActiveEvent activeEvent) { if (this.IsSimultaneous || this.PlaySimultaneous) { playable.PlaySimultaneous = true; } yield return(playable.PlayAsync(activeEvent)); }
/// <summary> /// Begin playing a non-continuous container, loop if applicable. /// </summary> private IEnumerator StartOneOffEventCoroutine(ActiveEvent activeEvent, UPlayable playable) { if (Loop) { yield return(PlayLoopingOneOffContainerCoroutine(activeEvent)); } else { yield return(PlayOneOffContainerCoroutine(activeEvent, playable)); } }
/// <summary> /// Play a non-continuous container. /// </summary> private IEnumerator PlayOneOffContainerCoroutine(ActiveEvent activeEvent, UPlayable playable) { // Simultaneous sounds. if (this.IsSimultaneous) { foreach (UPlayable sound in sounds) { // We start coroutines here. Since we want to all the sounds to start playing at the same time. StartCoroutine(PlayClipCoroutine(sound, activeEvent)); } } // Sequential and Random sounds. else { yield return(PlayClipCoroutine(playable, activeEvent)); } }
/// <summary> /// Determine which rules to follow for container playback, and begin the appropriate function. /// </summary> public override IEnumerator PlayAsync(ActiveEvent activeEvent) { BeginPlay(); if (sounds.Length == 0) { Debug.LogErrorFormat(this, "Trying to play container \"{0}\" with no clips.", this); yield break; } // We store the playable before the delay, so that we have the correct one in the case where another instance (without delay) was started. UPlayable currentPlayable = null; if (this.currentClipIndex.HasValue) { currentPlayable = CurrentPlayable; } if (this.CurrentDelay > 0.0f) { yield return(new WaitForSeconds(this.CurrentDelay)); } if (!activeEvent.StopRequested) { switch (containerType) { case AudioContainerType.Random: case AudioContainerType.Simultaneous: case AudioContainerType.Sequence: yield return(StartOneOffEventCoroutine(activeEvent, currentPlayable)); break; case AudioContainerType.ContinuousSequence: case AudioContainerType.ContinuousRandom: yield return(PlayContinuousContainerCoroutine(activeEvent)); break; default: Debug.LogErrorFormat(this, "Trying to play container \"{0}\" with an unknown AudioContainerType \"{1}\".", this, containerType); yield break; } } }
/// <summary> /// Coroutine for "continuous" containers that alternates between two sources to crossfade clips for continuous playlist looping. /// </summary> /// <returns>The coroutine.</returns> private IEnumerator PlayContinuousContainerCoroutine(ActiveEvent activeEvent) { float waitTime = 0; int? currentIndex = null; while (!activeEvent.StopRequested) { currentIndex = this.GenerateNextClipIndex(currentIndex); UPlayable tempClip = this.sounds[currentIndex.Value]; if (tempClip.IsEmpty()) { Debug.LogErrorFormat(this, "Sound clip in event \"{0}\" is null!", activeEvent.audioEvent.name); waitTime = 0; } else { if (!activeEvent.IsPlayingSecondary) { activeEvent.volDest = activeEvent.audioEvent.volumeCenter; activeEvent.altVolDest = 0f; } else { activeEvent.volDest = 0f; activeEvent.altVolDest = activeEvent.audioEvent.volumeCenter; } activeEvent.CurrentAudioSource.volume = 0f; activeEvent.currentFade = crossfadeTime; yield return(PlayClipCoroutine(tempClip, activeEvent)); waitTime = tempClip.GetLength() - crossfadeTime; } // Alternate playing on primary / secondary audio sources. activeEvent.IsPlayingSecondary = !activeEvent.IsPlayingSecondary; yield return(new WaitForSeconds(waitTime)); } }
private void AddSound(AudioContainer audioContainer, SerializedObject audioContainerSO, UPlayable newPlayable) { if (audioContainer.sounds == null) { audioContainer.sounds = new UPlayable[0]; } audioContainerSO.FindProperty("sounds").InsertArrayElementAtIndex(audioContainer.sounds.Length); audioContainerSO.FindProperty("sounds").GetArrayElementAtIndex(audioContainer.sounds.Length).objectReferenceValue = newPlayable; }
private void DrawSoundClipInspector(AudioContainer audioContainer, SerializedObject audioContainerSerializedObject) { bool oldAllowLooping = allowLooping; allowLooping = allowLooping && !audioContainer.Loop && !audioContainer.IsContinuous; for (int i = 0; audioContainer.sounds != null && i < audioContainer.sounds.Length; i++) { if (audioContainer.sounds[i] == null) { UAudioClip audioClip = this.playablesGameObject.AddComponent <UAudioClip>(); audioContainer.sounds[i] = audioClip; } UPlayable currentSound = audioContainer.sounds[i]; EditorGUILayout.Space(); EditorGUILayout.Space(); bool wasRemoved = false; EditorGUILayout.BeginHorizontal(); soundElementArrowsStyle.margin.top = allowLooping ? 10 : 0; EditorGUILayout.BeginVertical(soundElementArrowsStyle); EditorGUI.BeginDisabledGroup(i <= 0); if (GUILayout.Button("▲", GUILayout.Width(20), GUILayout.Height(15))) { MoveSound(audioContainer, audioContainerSerializedObject, i, -1); } EditorGUI.EndDisabledGroup(); EditorGUI.BeginDisabledGroup(i >= audioContainer.sounds.Length - 1); if (GUILayout.Button("▼", GUILayout.Width(20), GUILayout.Height(15))) { MoveSound(audioContainer, audioContainerSerializedObject, i, 1); } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); if (currentSound is UAudioClip) { DrawAudioClipInspector(audioContainer, (UAudioClip)currentSound, out wasRemoved); } else if (currentSound is AudioContainer) { DrawContainerInspector((AudioContainer)currentSound, true, out wasRemoved); } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); if (wasRemoved) { audioContainerSerializedObject.FindProperty("sounds").GetArrayElementAtIndex(i).DeleteCommand(); audioContainerSerializedObject.FindProperty("sounds").DeleteArrayElementAtIndex(i); DestroyImmediate(currentSound); RemoveAt(audioContainer.sounds, i); } } allowLooping = oldAllowLooping; }