Beispiel #1
0
        /// <summary>
        /// Play a single clip on an AudioSource; if Looping forever, return InfiniteLoop for the event time.
        /// </summary>
        /// <param Name="audioClip">The audio clip to play.</param>
        /// <param Name="emitter">The emitter to use.</param>
        /// <param Name="activeEvent">The persistent reference to the event as long as it is playing.</param>
        /// <returns>The amount of delay, if any, we are waiting before playing the clip. A Looping clip will always return InfiniteLoop.</returns>
        private float PlayClipAndGetTime(UAudioClip audioClip, AudioSource emitter, ActiveEvent activeEvent)
        {
            if (audioClip.DelayCenter == 0)
            {
                emitter.PlayClip(audioClip.Sound, audioClip.Looping);

                if (audioClip.Looping)
                {
                    return(InfiniteLoop);
                }

                return(0);
            }
            else
            {
                float rndDelay = Random.Range(audioClip.DelayCenter - audioClip.DelayRandomization, audioClip.DelayCenter + audioClip.DelayRandomization);

                StartCoroutine(PlayClipDelayedCoroutine(audioClip, emitter, rndDelay, activeEvent));

                if (audioClip.Looping)
                {
                    return(InfiniteLoop);
                }

                return(rndDelay);
            }
        }
Beispiel #2
0
 private void AddSound(TEvent selectedEvent)
 {
     UAudioClip[] tempClips = new UAudioClip[selectedEvent.container.sounds.Length + 1];
     selectedEvent.container.sounds.CopyTo(tempClips, 0);
     tempClips[tempClips.Length - 1] = new UAudioClip();
     selectedEvent.container.sounds  = tempClips;
 }
Beispiel #3
0
        /// <summary>
        /// Coroutine for "continuous" random containers that alternates between two sources to crossfade clips for continuous playlist Looping.
        /// </summary>
        /// <param Name="audioContainer">The audio container.</param>
        /// <param Name="activeEvent">The persistent reference to the event as long as it is playing.</param>
        /// <param Name="waitTime">The time in seconds to wait before switching AudioSources for crossfading.</param>
        /// <returns>The coroutine.</returns>
        private IEnumerator ContinueRandomContainerCoroutine(AudioContainer audioContainer, ActiveEvent activeEvent, float waitTime)
        {
            while (!activeEvent.CancelEvent)
            {
                yield return(new WaitForSeconds(waitTime));

                audioContainer.CurrentClip = Random.Range(0, audioContainer.Sounds.Length);
                UAudioClip tempClip = audioContainer.Sounds[audioContainer.CurrentClip];

                // Play on primary source.
                if (activeEvent.PlayingAlt)
                {
                    activeEvent.PrimarySource.volume = 0f;
                    activeEvent.VolDest     = activeEvent.AudioEvent.VolumeCenter;
                    activeEvent.AltVolDest  = 0f;
                    activeEvent.CurrentFade = audioContainer.CrossfadeTime;
                    waitTime = (tempClip.Sound.length / activeEvent.PrimarySource.pitch) - audioContainer.CrossfadeTime;
                    PlayClipAndGetTime(tempClip, activeEvent.PrimarySource, activeEvent);
                }
                // Play on secondary source.
                else
                {
                    activeEvent.SecondarySource.volume = 0f;
                    activeEvent.AltVolDest             = activeEvent.AudioEvent.VolumeCenter;
                    activeEvent.VolDest     = 0f;
                    activeEvent.CurrentFade = audioContainer.CrossfadeTime;
                    waitTime = (tempClip.Sound.length / activeEvent.SecondarySource.pitch) - audioContainer.CrossfadeTime;
                    PlayClipAndGetTime(tempClip, activeEvent.SecondarySource, activeEvent);
                }

                activeEvent.PlayingAlt = !activeEvent.PlayingAlt;
            }
        }
Beispiel #4
0
        /// <summary>
        /// Play one sound from a container based on container behavior.
        /// </summary>
        /// <param Name="currentContainer"></param>
        /// <param Name="activeEvent"></param>
        /// <returns>The estimated ActiveTime for the clip, or InfiniteLoop if the container and/or clip are set to loop.</returns>
        private float PlaySingleClip(AudioContainer currentContainer, ActiveEvent activeEvent)
        {
            float tempDelay = 0;

            if (currentContainer.ContainerType == AudioContainerType.Random)
            {
                currentContainer.CurrentClip = Random.Range(0, currentContainer.Sounds.Length);
            }
            UAudioClip currentClip = currentContainer.Sounds[currentContainer.CurrentClip];

            // Trigger sound and save the delay (in seconds) to add to the total amount of time the event will be considered active.
            tempDelay = PlayClipAndGetTime(currentClip, activeEvent.PrimarySource, activeEvent);

            // Ready the next clip in the series if sequence container.
            if (currentContainer.ContainerType == AudioContainerType.Sequence)
            {
                currentContainer.CurrentClip++;
                if (currentContainer.CurrentClip >= currentContainer.Sounds.Length)
                {
                    currentContainer.CurrentClip = 0;
                }
            }

            // Return active time based on Looping or clip time.
            return(GetActiveTimeEstimate(currentClip, activeEvent, tempDelay));
        }
Beispiel #5
0
        /// <summary>
        /// Coroutine for playing a clip after a delay (in seconds).
        /// </summary>
        /// <param Name="audioClip">The clip to play.</param>
        /// <param Name="emitter">The emitter to use.</param>
        /// <param Name="delay">The amount of time in seconds to wait before playing audio clip.</param>
        /// <param Name="activeEvent">The persistent reference to the event as long as it is playing.</param>
        /// <returns>The coroutine.</returns>
        private IEnumerator PlayClipDelayedCoroutine(UAudioClip audioClip, AudioSource emitter, float delay, ActiveEvent activeEvent)
        {
            yield return(new WaitForSeconds(delay));

            if (this.ActiveEvents.Contains(activeEvent))
            {
                emitter.PlayClip(audioClip.Sound, audioClip.Looping);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Calculates the estimated active time for an ActiveEvent playing the given clip.
        /// </summary>
        /// <param Name="audioClip">The clip being played.</param>
        /// <param Name="activeEvent">The event being played.</param>
        /// <param Name="additionalDelay">The delay before playing in seconds.</param>
        /// <returns>The estimated active time of the event based on Looping or clip time. If Looping, this will return InfiniteLoop.</returns>
        private static float GetActiveTimeEstimate(UAudioClip audioClip, ActiveEvent activeEvent, float additionalDelay)
        {
            if (audioClip.Looping || activeEvent.AudioEvent.Container.Looping || additionalDelay == InfiniteLoop)
            {
                return(InfiniteLoop);
            }
            else
            {
                float pitchAdjustedClipLength = activeEvent.PrimarySource.pitch != 0 ? (audioClip.Sound.length / activeEvent.PrimarySource.pitch) : 0;

                // Restrict non-Looping ActiveTime values to be non-negative.
                return(Mathf.Max(0.0f, pitchAdjustedClipLength + activeEvent.AudioEvent.InstanceTimeBuffer + additionalDelay));
            }
        }
Beispiel #7
0
        /// <summary>
        /// Coroutine for "continuous" sequence containers that alternates between two sources to crossfade clips for continuous playlist Looping.
        /// </summary>
        /// <param Name="audioContainer">The audio container.</param>
        /// <param Name="activeEvent">The persistent reference to the event as long as it is playing.</param>
        /// <param Name="waitTime">The time in seconds to wait before switching AudioSources to crossfading.</param>
        /// <returns>The coroutine.</returns>
        private IEnumerator ContinueSequenceContainerCoroutine(AudioContainer audioContainer, ActiveEvent activeEvent, float waitTime)
        {
            while (!activeEvent.CancelEvent)
            {
                yield return(new WaitForSeconds(waitTime));

                UAudioClip tempClip = audioContainer.Sounds[audioContainer.CurrentClip];
                if (tempClip.Sound == null)
                {
                    Debug.LogErrorFormat(this, "Sound clip in event \"{0}\" is null!", activeEvent.AudioEvent.Name);
                    waitTime = 0;
                }
                else
                {
                    // Play on primary source.
                    if (activeEvent.PlayingAlt)
                    {
                        activeEvent.PrimarySource.volume = 0f;
                        activeEvent.VolDest     = activeEvent.AudioEvent.VolumeCenter;
                        activeEvent.AltVolDest  = 0f;
                        activeEvent.CurrentFade = audioContainer.CrossfadeTime;
                        waitTime = (tempClip.Sound.length / activeEvent.PrimarySource.pitch) - audioContainer.CrossfadeTime;
                        PlayClipAndGetTime(tempClip, activeEvent.PrimarySource, activeEvent);
                    }
                    // Play on secondary source.
                    else
                    {
                        activeEvent.SecondarySource.volume = 0f;
                        activeEvent.AltVolDest             = activeEvent.AudioEvent.VolumeCenter;
                        activeEvent.VolDest     = 0f;
                        activeEvent.CurrentFade = audioContainer.CrossfadeTime;
                        waitTime = (tempClip.Sound.length / activeEvent.SecondarySource.pitch) - audioContainer.CrossfadeTime;
                        PlayClipAndGetTime(tempClip, activeEvent.SecondarySource, activeEvent);
                    }
                }

                audioContainer.CurrentClip++;

                if (audioContainer.CurrentClip >= audioContainer.Sounds.Length)
                {
                    audioContainer.CurrentClip = 0;
                }

                activeEvent.PlayingAlt = !activeEvent.PlayingAlt;
            }
        }
Beispiel #8
0
        private void DrawAudioClipInspector(AudioContainer audioContainer, UAudioClip currentSound, out bool wasRemoved)
        {
            EditorGUILayout.BeginHorizontal();

            SerializedObject playableSO = new SerializedObject(currentSound);

            playableSO.Update();

            EditorGUILayout.PropertyField(playableSO.FindProperty("sound"));

            if (GUILayout.Button("Remove Audio Clip"))
            {
                playableSO.Dispose();

                EditorGUILayout.EndHorizontal();

                wasRemoved = true;
                return;
            }

            EditorGUILayout.EndHorizontal();

            if (!audioContainer.IsContinuous)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PropertyField(playableSO.FindProperty("delayCenter"));
                EditorGUILayout.PropertyField(playableSO.FindProperty("delayRandomization"));

                EditorGUILayout.EndHorizontal();

                // Disable looping audio clips in a simultaneous container.
                // Looping containers within a simultaneous container is allowed.
                if (allowLooping && !audioContainer.IsSimultaneous)
                {
                    EditorGUILayout.PropertyField(playableSO.FindProperty("loop"));
                }
                else
                {
                    currentSound.Loop = false;
                }
            }

            playableSO.ApplyModifiedProperties();
            wasRemoved = false;
        }
Beispiel #9
0
        /// <summary>
        /// Choose a random sound from a container and play, calling the Looping coroutine to constantly choose new audio clips when current clip ends.
        /// </summary>
        /// <param Name="audioContainer">The audio container.</param>
        /// <param Name="emitter">The emitter to use.</param>
        /// <param Name="activeEvent">The persistent reference to the event as long as it is playing.</param>
        private void PlayContinuousRandomContainer(AudioContainer audioContainer, AudioSource emitter, ActiveEvent activeEvent)
        {
            audioContainer.CurrentClip = Random.Range(0, audioContainer.Sounds.Length);
            UAudioClip tempClip = audioContainer.Sounds[audioContainer.CurrentClip];

            activeEvent.PrimarySource.volume = 0f;
            activeEvent.VolDest     = activeEvent.AudioEvent.VolumeCenter;
            activeEvent.AltVolDest  = 0f;
            activeEvent.CurrentFade = audioContainer.CrossfadeTime;

            float waitTime = (tempClip.Sound.length / emitter.pitch) - activeEvent.AudioEvent.Container.CrossfadeTime;

            // Ignore clip delay since container is continuous.
            PlayClipAndGetTime(tempClip, emitter, activeEvent);
            activeEvent.ActiveTime = InfiniteLoop;
            StartCoroutine(RecordEventInstanceCoroutine(activeEvent));
            audioContainer.CurrentClip++;
            if (audioContainer.CurrentClip >= audioContainer.Sounds.Length)
            {
                audioContainer.CurrentClip = 0;
            }
            StartCoroutine(ContinueRandomContainerCoroutine(audioContainer, activeEvent, waitTime));
        }
Beispiel #10
0
        private void AddAudioClip(AudioContainer audioContainer, SerializedObject audioContainerSO)
        {
            UAudioClip audioClip = this.playablesGameObject.AddComponent <UAudioClip>();

            AddSound(audioContainer, audioContainerSO, audioClip);
        }
Beispiel #11
0
        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;
        }