using System;
using UnityEngine;
using UnityEngine.UI;
namespace MoreMountains.Tools
{
///
/// You can add this class to a slider in your UI and it'll let you control a target Track volume
/// via the MMSoundManager
///
public class MMSoundManagerTrackVolumeSlider : MonoBehaviour,
MMEventListener,
MMEventListener,
MMEventListener
{
///
/// 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
///
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;
///
/// On awake we cache our slider
///
protected virtual void Awake()
{
_slider = this.gameObject.GetComponent();
}
///
/// On late update, we update our slider's value if in read mode, and reset our mode if needed
///
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;
}
}
///
/// A public method you can use to switch to read mode for a limited time, resetting to write after that
///
///
public virtual void ChangeModeToRead(float duration)
{
_resetToMode = Modes.Write;
Mode = Modes.Read;
_resetTimestamp = Time.unscaledTime + duration;
_resetNeeded = true;
}
///
/// Bind your slider to this method
///
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);
}
///
/// When we get an event letting us know the settings have been loaded, we update our slider to reflect the current track volume
///
///
public void OnMMEvent(MMSoundManagerEvent soundManagerEvent)
{
if (soundManagerEvent.EventType == MMSoundManagerEventTypes.SettingsLoaded)
{
UpdateSliderValueWithTrackVolume();
}
}
///
/// Updates the slider value to reflect the current track volume
///
public virtual void UpdateSliderValueWithTrackVolume()
{
_slider.value = MMMaths.Remap(MMSoundManager.Instance.GetTrackVolume(Track, false), 0f, 1f, MinVolume, MaxVolume);
}
///
/// if we grab a track event, we switch to read mode if needed
///
///
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;
}
}
///
/// if we grab a track fade event, we switch to read mode if needed
///
///
public void OnMMEvent(MMSoundManagerTrackFadeEvent fadeEvent)
{
if (ChangeModeOnTrackFade)
{
ChangeModeToRead(fadeEvent.FadeDuration + ModeSwitchBufferTime);
}
}
///
/// On enable we start listening for events
///
protected virtual void OnEnable()
{
this.MMEventStartListening();
this.MMEventStartListening();
this.MMEventStartListening();
}
///
/// On disable we stop listening for events
///
protected virtual void OnDisable()
{
this.MMEventStopListening();
this.MMEventStopListening();
this.MMEventStopListening();
}
}
}