// Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. using UnityEngine; namespace Meta.XR.Movement.Samples { /// /// Trigger an audio clip on this audio source. /// Copied from Meta XR Interaction SDK OVR Samples. /// public class MovementAudioTrigger : MonoBehaviour { /// /// Struct that contains data about a min max pair of floats. /// [System.Serializable] public struct MinMaxPair { /// public bool UseRandomRange => _useRandomRange; /// public float Min => _min; /// public float Max => _max; /// /// True if random range should be used. /// [SerializeField] private bool _useRandomRange; /// /// The minimum float. /// [SerializeField] private float _min; /// /// The maximum float. /// [SerializeField] private float _max; } /// /// The audio source used to trigger audio. /// [SerializeField] private AudioSource _audioSource; /// /// Audio clip arrays with a value greater than 1 will have randomized playback. /// [Tooltip("Audio clip arrays with a value greater than 1 will have randomized playback.")] [SerializeField] private AudioClip[] _audioClips; /// /// Volume set here will override the volume set on the attached sound source component. /// [Tooltip("Volume set here will override the volume set on the attached sound source component.")] [Range(0f, 1f)] [SerializeField] private float _volume = 0.7f; /// public float Volume { get => _volume; set => _volume = value; } /// /// Check the 'Use Random Range' bool to and adjust the min and max slider values for randomized volume level playback. /// [Tooltip("Check the 'Use Random Range' bool to and adjust the min and max slider values for randomized volume level playback.")] [SerializeField] private MinMaxPair _volumeRandomization; /// public MinMaxPair VolumeRandomization { get => _volumeRandomization; set => _volumeRandomization = value; } /// /// Pitch set here will override the volume set on the attached sound source component. /// [Tooltip("Pitch set here will override the volume set on the attached sound source component.")] [SerializeField] [Range(-3f, 3f)] [Space(10)] private float _pitch = 1f; /// public float Pitch { get => _pitch; set => _pitch = value; } /// /// Check the 'Use Random Range' bool to and adjust the min and max slider values for randomized volume level playback. /// [Tooltip("Check the 'Use Random Range' bool to and adjust the min and max slider values for randomized volume level playback.")] [SerializeField] private MinMaxPair _pitchRandomization; /// public MinMaxPair PitchRandomization { get => _pitchRandomization; set => _pitchRandomization = value; } /// /// True by default. Set to false for sounds to bypass the spatializer plugin. Will override settings on attached audio source. /// [Tooltip("True by default. Set to false for sounds to bypass the spatializer plugin. Will override settings on attached audio source.")] [SerializeField] [Space(10)] private bool _spatialize = true; /// public bool Spatialize { get => _spatialize; set => _spatialize = value; } /// /// False by default. Set to true to enable looping on this sound. Will override settings on attached audio source. /// [Tooltip("False by default. Set to true to enable looping on this sound. Will override settings on attached audio source.")] [SerializeField] private bool _loop = false; /// public bool Loop { get => _loop; set => _loop = value; } /// /// 100% by default. Sets likelyhood sample will actually play when called. /// [Tooltip("100% by default. Sets likelyhood sample will actually play when called.")] [SerializeField] private float _chanceToPlay = 100; /// public float ChanceToPlay { get => _chanceToPlay; set => _chanceToPlay = value; } /// /// If enabled, audio will play automatically when this gameobject is enabled. /// [Tooltip("If enabled, audio will play automatically when this gameobject is enabled.")] [SerializeField] private bool _playOnStart = false; private int _previousAudioClipIndex = -1; protected virtual void Start() { if (_audioSource == null) { _audioSource = gameObject.GetComponent(); } // Play audio on start if enabled if (_playOnStart) { PlayAudio(); } } /// /// Play the audio clip on this audio source. /// public void PlayAudio() { // Check if random chance is set float pick = Random.Range(0.0f, 100.0f); if (_chanceToPlay < 100 && pick > _chanceToPlay) { return; } // Check if volume randomization is set if (_volumeRandomization.UseRandomRange == true) { _audioSource.volume = Random.Range(_volumeRandomization.Min, _volumeRandomization.Max); } else { _audioSource.volume = _volume; } // Check if pitch randomization is set if (_pitchRandomization.UseRandomRange == true) { _audioSource.pitch = Random.Range(_pitchRandomization.Min, _pitchRandomization.Max); } else { _audioSource.pitch = _pitch; } _audioSource.spatialize = _spatialize; _audioSource.loop = _loop; _audioSource.clip = RandomClipWithoutRepeat(); _audioSource.Play(); } /// /// Choose a random clip without repeating the last clip. /// private AudioClip RandomClipWithoutRepeat() { if (_audioClips.Length == 1) { return _audioClips[0]; } int randomOffset = Random.Range(1, _audioClips.Length); int index = (_previousAudioClipIndex + randomOffset) % _audioClips.Length; _previousAudioClipIndex = index; return _audioClips[index]; } #region Inject public void InjectAllAudioTrigger(AudioSource audioSource, AudioClip[] audioClips) { InjectAudioSource(audioSource); InjectAudioClips(audioClips); } public void InjectAudioSource(AudioSource audioSource) { _audioSource = audioSource; } public void InjectAudioClips(AudioClip[] audioClips) { _audioClips = audioClips; } public void InjectOptionalPlayOnStart(bool playOnStart) { _playOnStart = playOnStart; } #endregion } }