You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/Feel/MMTools/Tools/MMAudio/MMSoundManager/MMSoundManagerTrackVolumeSl...

196 lines
7.2 KiB
C#

3 months ago
using System;
using UnityEngine;
using UnityEngine.UI;
namespace MoreMountains.Tools
{
/// <summary>
/// You can add this class to a slider in your UI and it'll let you control a target Track volume
/// via the MMSoundManager
/// </summary>
public class MMSoundManagerTrackVolumeSlider : MonoBehaviour,
MMEventListener<MMSoundManagerEvent>,
MMEventListener<MMSoundManagerTrackEvent>,
MMEventListener<MMSoundManagerTrackFadeEvent>
{
/// <summary>
/// The possible modes this slider can be in
/// - Read : the slider will move to reflect the volume of the track
/// - Write : the value of the slider will be applied to the volume of the track
/// This slider can also listen for events (mute, unmute, fade, volume change) and automatically switch to read mode
/// if one is caught. This means that most of the time, the slider is in write mode, and switches to read mode only
/// when needed, to be always accurate
/// </summary>
public enum Modes { Read, Write }
[Header("Track Volume Settings")]
/// The track to change volume on
[Tooltip("The track to change volume on")]
public MMSoundManager.MMSoundManagerTracks Track;
/// The volume to apply to the track when the slider is at its minimum
[Tooltip("The volume to apply to the track when the slider is at its minimum")]
public float MinVolume = 0f;
/// The volume to apply to the track when the slider is at its maximum
[Tooltip("The volume to apply to the track when the slider is at its maximum")]
public float MaxVolume = 1f;
[Header("Read/Write Mode")]
/// in read mode, the value of the slider will be applied to the volume of the track. in read mode, the slider will move to reflect the volume of the track
[Tooltip("in read mode, the value of the slider will be applied to the volume of the track. in read mode, the slider will move to reflect the volume of the track")]
public Modes Mode = Modes.Write;
/// if this is true, the slider will automatically switch to read mode for the required duration when a track fade event is caught
[Tooltip("if this is true, the slider will automatically switch to read mode for the required duration when a track fade event is caught")]
public bool ChangeModeOnTrackFade = true;
/// if this is true, the slider will automatically switch to read mode for the required duration when a track mute event is caught
[Tooltip("if this is true, the slider will automatically switch to read mode for the required duration when a track mute event is caught")]
public bool ChangeModeOnMute = true;
/// if this is true, the slider will automatically switch to read mode for the required duration when a track unmute event is caught
[Tooltip("if this is true, the slider will automatically switch to read mode for the required duration when a track unmute event is caught")]
public bool ChangeModeOnUnmute = true;
/// if this is true, the slider will automatically switch to read mode for the required duration when a track volume change event is caught
[Tooltip("if this is true, the slider will automatically switch to read mode for the required duration when a track volume change event is caught")]
public bool ChangeModeOnTrackVolumeChange = false;
/// when switching automatically (and temporarily) to Read Mode, the minimum duration the slider will remain in that mode
[Tooltip("when switching automatically (and temporarily) to Read Mode, the minimum duration the slider will remain in that mode")]
public float ModeSwitchBufferTime = 0.1f;
protected Slider _slider;
protected Modes _resetToMode;
protected bool _resetNeeded = false;
protected float _resetTimestamp;
/// <summary>
/// On awake we cache our slider
/// </summary>
protected virtual void Awake()
{
_slider = this.gameObject.GetComponent<Slider>();
}
/// <summary>
/// On late update, we update our slider's value if in read mode, and reset our mode if needed
/// </summary>
protected virtual void LateUpdate()
{
if (Mode == Modes.Read)
{
float trackVolume = MMSoundManager.Instance.GetTrackVolume(Track, false);
_slider.value = trackVolume;
}
if (_resetNeeded && (Time.unscaledTime >= _resetTimestamp))
{
Mode = _resetToMode;
_resetNeeded = false;
}
}
/// <summary>
/// A public method you can use to switch to read mode for a limited time, resetting to write after that
/// </summary>
/// <param name="duration"></param>
public virtual void ChangeModeToRead(float duration)
{
_resetToMode = Modes.Write;
Mode = Modes.Read;
_resetTimestamp = Time.unscaledTime + duration;
_resetNeeded = true;
}
/// <summary>
/// Bind your slider to this method
/// </summary>
public virtual void UpdateVolume(float newValue)
{
if (Mode == Modes.Read)
{
return;
}
float newVolume = MMMaths.Remap(newValue, 0f, 1f, MinVolume, MaxVolume);
MMSoundManagerTrackEvent.Trigger(MMSoundManagerTrackEventTypes.SetVolumeTrack, Track, newVolume);
}
/// <summary>
/// When we get an event letting us know the settings have been loaded, we update our slider to reflect the current track volume
/// </summary>
/// <param name="soundManagerEvent"></param>
public void OnMMEvent(MMSoundManagerEvent soundManagerEvent)
{
if (soundManagerEvent.EventType == MMSoundManagerEventTypes.SettingsLoaded)
{
UpdateSliderValueWithTrackVolume();
}
}
/// <summary>
/// Updates the slider value to reflect the current track volume
/// </summary>
public virtual void UpdateSliderValueWithTrackVolume()
{
_slider.value = MMMaths.Remap(MMSoundManager.Instance.GetTrackVolume(Track, false), 0f, 1f, MinVolume, MaxVolume);
}
/// <summary>
/// if we grab a track event, we switch to read mode if needed
/// </summary>
/// <param name="trackEvent"></param>
public void OnMMEvent(MMSoundManagerTrackEvent trackEvent)
{
switch (trackEvent.TrackEventType)
{
case MMSoundManagerTrackEventTypes.MuteTrack:
if (ChangeModeOnMute)
{
ChangeModeToRead(ModeSwitchBufferTime);
}
break;
case MMSoundManagerTrackEventTypes.UnmuteTrack:
if (ChangeModeOnUnmute)
{
ChangeModeToRead(ModeSwitchBufferTime);
}
break;
case MMSoundManagerTrackEventTypes.SetVolumeTrack:
if (ChangeModeOnTrackVolumeChange)
{
ChangeModeToRead(ModeSwitchBufferTime);
}
break;
}
}
/// <summary>
/// if we grab a track fade event, we switch to read mode if needed
/// </summary>
/// <param name="fadeEvent"></param>
public void OnMMEvent(MMSoundManagerTrackFadeEvent fadeEvent)
{
if (ChangeModeOnTrackFade)
{
ChangeModeToRead(fadeEvent.FadeDuration + ModeSwitchBufferTime);
}
}
/// <summary>
/// On enable we start listening for events
/// </summary>
protected virtual void OnEnable()
{
this.MMEventStartListening<MMSoundManagerEvent>();
this.MMEventStartListening<MMSoundManagerTrackEvent>();
this.MMEventStartListening<MMSoundManagerTrackFadeEvent>();
}
/// <summary>
/// On disable we stop listening for events
/// </summary>
protected virtual void OnDisable()
{
this.MMEventStopListening<MMSoundManagerEvent>();
this.MMEventStopListening<MMSoundManagerTrackEvent>();
this.MMEventStopListening<MMSoundManagerTrackFadeEvent>();
}
}
}