Insanely huge initial commit

This commit is contained in:
2026-02-21 16:40:15 -08:00
parent 208d626100
commit f74c547a13
33825 changed files with 5213498 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
using UnityEngine;
using System.Collections;
using System;
using UnityEngine.UI;
using MoreMountains.Tools;
namespace MoreMountains.Tools
{
/// <summary>
/// Add this class to an object and it'll make sure that the cursor is either visible or invisible
/// </summary>
[AddComponentMenu("More Mountains/Tools/GUI/MMCursorVisible")]
public class MMCursorVisible : MonoBehaviour
{
/// The possible states of the cursor
public enum CursorVisibilities { Visible, Invisible }
/// Whether that cursor should be visible or invisible
public CursorVisibilities CursorVisibility = CursorVisibilities.Visible;
/// <summary>
/// On Update we change the status of our cursor accordingly
/// </summary>
protected virtual void Update()
{
if (CursorVisibility == CursorVisibilities.Visible)
{
Cursor.visible = true;
}
else
{
Cursor.visible = false;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 98e84bec6c36ca5419922f3def4d4267
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,472 @@
using UnityEngine;
using System.Collections;
using System;
using UnityEngine.UI;
using MoreMountains.Tools;
namespace MoreMountains.Tools
{
/// <summary>
/// An event used to stop fades
/// </summary>
public struct MMFadeStopEvent
{
/// an ID that has to match the one on the fader
public int ID;
public bool Restore;
public MMFadeStopEvent(int id = 0, bool restore = false)
{
Restore = restore;
ID = id;
}
static MMFadeStopEvent e;
public static void Trigger(int id = 0, bool restore = false)
{
e.ID = id;
e.Restore = restore;
MMEventManager.TriggerEvent(e);
}
}
/// <summary>
/// Events used to trigger faders on or off
/// </summary>
public struct MMFadeEvent
{
/// an ID that has to match the one on the fader
public int ID;
/// the duration of the fade, in seconds
public float Duration;
/// the alpha to aim for
public float TargetAlpha;
/// the curve to apply to the fade
public MMTweenType Curve;
/// whether or not this fade should ignore timescale
public bool IgnoreTimeScale;
/// a world position for a target object. Useless for regular fades, but can be useful for alt implementations (circle fade for example)
public Vector3 WorldPosition;
/// <summary>
/// Initializes a new instance of the <see cref="MoreMountains.MMInterface.MMFadeEvent"/> struct.
/// </summary>
/// <param name="duration">Duration, in seconds.</param>
/// <param name="targetAlpha">Target alpha, from 0 to 1.</param>
public MMFadeEvent(float duration, float targetAlpha, MMTweenType tween, int id=0,
bool ignoreTimeScale = true, Vector3 worldPosition = new Vector3())
{
ID = id;
Duration = duration;
TargetAlpha = targetAlpha;
Curve = tween;
IgnoreTimeScale = ignoreTimeScale;
WorldPosition = worldPosition;
}
static MMFadeEvent e;
public static void Trigger(float duration, float targetAlpha)
{
Trigger(duration, targetAlpha, new MMTweenType(MMTween.MMTweenCurve.EaseInCubic));
}
public static void Trigger(float duration, float targetAlpha, MMTweenType tween, int id = 0,
bool ignoreTimeScale = true, Vector3 worldPosition = new Vector3())
{
e.ID = id;
e.Duration = duration;
e.TargetAlpha = targetAlpha;
e.Curve = tween;
e.IgnoreTimeScale = ignoreTimeScale;
e.WorldPosition = worldPosition;
MMEventManager.TriggerEvent(e);
}
}
public struct MMFadeInEvent
{
/// an ID that has to match the one on the fader
public int ID;
/// the duration of the fade, in seconds
public float Duration;
/// the curve to apply to the fade
public MMTweenType Curve;
/// whether or not this fade should ignore timescale
public bool IgnoreTimeScale;
/// a world position for a target object. Useless for regular fades, but can be useful for alt implementations (circle fade for example)
public Vector3 WorldPosition;
/// <summary>
/// Initializes a new instance of the <see cref="MoreMountains.MMInterface.MMFadeInEvent"/> struct.
/// </summary>
/// <param name="duration">Duration.</param>
public MMFadeInEvent(float duration, MMTweenType tween, int id = 0,
bool ignoreTimeScale = true, Vector3 worldPosition = new Vector3())
{
ID = id;
Duration = duration;
Curve = tween;
IgnoreTimeScale = ignoreTimeScale;
WorldPosition = worldPosition;
}
static MMFadeInEvent e;
public static void Trigger(float duration, MMTweenType tween, int id = 0,
bool ignoreTimeScale = true, Vector3 worldPosition = new Vector3())
{
e.ID = id;
e.Duration = duration;
e.Curve = tween;
e.IgnoreTimeScale = ignoreTimeScale;
e.WorldPosition = worldPosition;
MMEventManager.TriggerEvent(e);
}
}
public struct MMFadeOutEvent
{
/// an ID that has to match the one on the fader
public int ID;
/// the duration of the fade, in seconds
public float Duration;
/// the curve to apply to the fade
public MMTweenType Curve;
/// whether or not this fade should ignore timescale
public bool IgnoreTimeScale;
/// a world position for a target object. Useless for regular fades, but can be useful for alt implementations (circle fade for example)
public Vector3 WorldPosition;
/// <summary>
/// Initializes a new instance of the <see cref="MoreMountains.MMInterface.MMFadeOutEvent"/> struct.
/// </summary>
/// <param name="duration">Duration.</param>
public MMFadeOutEvent(float duration, MMTweenType tween, int id = 0,
bool ignoreTimeScale = true, Vector3 worldPosition = new Vector3())
{
ID = id;
Duration = duration;
Curve = tween;
IgnoreTimeScale = ignoreTimeScale;
WorldPosition = worldPosition;
}
static MMFadeOutEvent e;
public static void Trigger(float duration, MMTweenType tween, int id = 0,
bool ignoreTimeScale = true, Vector3 worldPosition = new Vector3())
{
e.ID = id;
e.Duration = duration;
e.Curve = tween;
e.IgnoreTimeScale = ignoreTimeScale;
e.WorldPosition = worldPosition;
MMEventManager.TriggerEvent(e);
}
}
/// <summary>
/// The Fader class can be put on an Image, and it'll intercept MMFadeEvents and turn itself on or off accordingly.
/// </summary>
[RequireComponent(typeof(CanvasGroup))]
[RequireComponent(typeof(Image))]
[AddComponentMenu("More Mountains/Tools/GUI/MMFader")]
public class MMFader : MonoBehaviour, MMEventListener<MMFadeEvent>, MMEventListener<MMFadeInEvent>, MMEventListener<MMFadeOutEvent>, MMEventListener<MMFadeStopEvent>
{
public enum ForcedInitStates { None, Active, Inactive }
[Header("Identification")]
/// the ID for this fader (0 is default), set more IDs if you need more than one fader
[Tooltip("the ID for this fader (0 is default), set more IDs if you need more than one fader")]
public int ID;
[Header("Opacity")]
/// the opacity the fader should be at when inactive
[Tooltip("the opacity the fader should be at when inactive")]
public float InactiveAlpha = 0f;
/// the opacity the fader should be at when active
[Tooltip("the opacity the fader should be at when active")]
public float ActiveAlpha = 1f;
/// determines whether a state should be forced on init
[Tooltip("determines whether a state should be forced on init")]
public ForcedInitStates ForcedInitState = ForcedInitStates.Inactive;
[Header("Timing")]
/// the default duration of the fade in/out
[Tooltip("the default duration of the fade in/out")]
public float DefaultDuration = 0.2f;
/// the default curve to use for this fader
[Tooltip("the default curve to use for this fader")]
public MMTweenType DefaultTween = new MMTweenType(MMTween.MMTweenCurve.LinearTween);
/// whether or not the fade should happen in unscaled time
[Tooltip("whether or not the fade should happen in unscaled time")]
public bool IgnoreTimescale = true;
/// whether or not this fader can cause a fade if the requested final alpha is the same as the current one
[Tooltip("whether or not this fader can cause a fade if the requested final alpha is the same as the current one")]
public bool CanFadeToCurrentAlpha = true;
[Header("Interaction")]
/// whether or not the fader should block raycasts when visible
[Tooltip("whether or not the fader should block raycasts when visible")]
public bool ShouldBlockRaycasts = false;
[Header("Debug")]
[MMInspectorButton("FadeIn1Second")]
public bool FadeIn1SecondButton;
[MMInspectorButton("FadeOut1Second")]
public bool FadeOut1SecondButton;
[MMInspectorButton("DefaultFade")]
public bool DefaultFadeButton;
[MMInspectorButton("ResetFader")]
public bool ResetFaderButton;
protected CanvasGroup _canvasGroup;
protected Image _image;
protected float _initialAlpha;
protected float _currentTargetAlpha;
protected float _currentDuration;
protected MMTweenType _currentCurve;
protected bool _fading = false;
protected float _fadeStartedAt;
protected bool _frameCountOne;
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void ResetFader()
{
_canvasGroup.alpha = InactiveAlpha;
}
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void DefaultFade()
{
MMFadeEvent.Trigger(DefaultDuration, ActiveAlpha, DefaultTween, ID);
}
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void FadeIn1Second()
{
MMFadeInEvent.Trigger(1f, new MMTweenType(MMTween.MMTweenCurve.LinearTween));
}
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void FadeOut1Second()
{
MMFadeOutEvent.Trigger(1f, new MMTweenType(MMTween.MMTweenCurve.LinearTween));
}
/// <summary>
/// On Start, we initialize our fader
/// </summary>
protected virtual void Awake()
{
Initialization();
}
/// <summary>
/// On init, we grab our components, and disable/hide everything
/// </summary>
protected virtual void Initialization()
{
_canvasGroup = GetComponent<CanvasGroup>();
_image = GetComponent<Image>();
if (ForcedInitState == ForcedInitStates.Inactive)
{
_canvasGroup.alpha = InactiveAlpha;
_image.enabled = false;
}
else if (ForcedInitState == ForcedInitStates.Active)
{
_canvasGroup.alpha = ActiveAlpha;
_image.enabled = true;
}
}
/// <summary>
/// On Update, we update our alpha
/// </summary>
protected virtual void Update()
{
if (_canvasGroup == null) { return; }
if (_fading)
{
Fade();
}
}
/// <summary>
/// Fades the canvasgroup towards its target alpha
/// </summary>
protected virtual void Fade()
{
float currentTime = IgnoreTimescale ? Time.unscaledTime : Time.time;
if (_frameCountOne)
{
if (Time.frameCount <= 2)
{
_canvasGroup.alpha = _initialAlpha;
return;
}
_fadeStartedAt = IgnoreTimescale ? Time.unscaledTime : Time.time;
currentTime = _fadeStartedAt;
_frameCountOne = false;
}
float endTime = _fadeStartedAt + _currentDuration;
if (currentTime - _fadeStartedAt < _currentDuration)
{
float result = MMTween.Tween(currentTime, _fadeStartedAt, endTime, _initialAlpha, _currentTargetAlpha, _currentCurve);
_canvasGroup.alpha = result;
}
else
{
StopFading();
}
}
/// <summary>
/// Stops the fading.
/// </summary>
protected virtual void StopFading()
{
_canvasGroup.alpha = _currentTargetAlpha;
_fading = false;
if (_canvasGroup.alpha == InactiveAlpha)
{
DisableFader();
}
}
/// <summary>
/// Disables the fader.
/// </summary>
protected virtual void DisableFader()
{
_image.enabled = false;
if (ShouldBlockRaycasts)
{
_canvasGroup.blocksRaycasts = false;
}
}
/// <summary>
/// Enables the fader.
/// </summary>
protected virtual void EnableFader()
{
_image.enabled = true;
if (ShouldBlockRaycasts)
{
_canvasGroup.blocksRaycasts = true;
}
}
/// <summary>
/// Starts fading this fader from the specified initial alpha to the target
/// </summary>
/// <param name="initialAlpha"></param>
/// <param name="endAlpha"></param>
/// <param name="duration"></param>
/// <param name="curve"></param>
/// <param name="id"></param>
/// <param name="ignoreTimeScale"></param>
protected virtual void StartFading(float initialAlpha, float endAlpha, float duration, MMTweenType curve, int id, bool ignoreTimeScale)
{
if (id != ID)
{
return;
}
if ((!CanFadeToCurrentAlpha) && (_canvasGroup.alpha == endAlpha))
{
return;
}
IgnoreTimescale = ignoreTimeScale;
EnableFader();
_fading = true;
_initialAlpha = initialAlpha;
_currentTargetAlpha = endAlpha;
_fadeStartedAt = IgnoreTimescale ? Time.unscaledTime : Time.time;
_currentCurve = curve;
_currentDuration = duration;
if (Time.frameCount == 1)
{
_frameCountOne = true;
}
}
/// <summary>
/// When catching a fade event, we fade our image in or out
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeEvent fadeEvent)
{
_currentTargetAlpha = (fadeEvent.TargetAlpha == -1) ? ActiveAlpha : fadeEvent.TargetAlpha;
StartFading(_canvasGroup.alpha, _currentTargetAlpha, fadeEvent.Duration, fadeEvent.Curve, fadeEvent.ID, fadeEvent.IgnoreTimeScale);
}
/// <summary>
/// When catching an MMFadeInEvent, we fade our image in
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeInEvent fadeEvent)
{
StartFading(InactiveAlpha, ActiveAlpha, fadeEvent.Duration, fadeEvent.Curve, fadeEvent.ID, fadeEvent.IgnoreTimeScale);
}
/// <summary>
/// When catching an MMFadeOutEvent, we fade our image out
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeOutEvent fadeEvent)
{
StartFading(ActiveAlpha, InactiveAlpha, fadeEvent.Duration, fadeEvent.Curve, fadeEvent.ID, fadeEvent.IgnoreTimeScale);
}
/// <summary>
/// When catching an MMFadeStopEvent, we stop our fade
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeStopEvent fadeStopEvent)
{
if (fadeStopEvent.ID == ID)
{
_fading = false;
if (fadeStopEvent.Restore)
{
_canvasGroup.alpha = _initialAlpha;
}
}
}
/// <summary>
/// On enable, we start listening to events
/// </summary>
protected virtual void OnEnable()
{
this.MMEventStartListening<MMFadeEvent>();
this.MMEventStartListening<MMFadeStopEvent>();
this.MMEventStartListening<MMFadeInEvent>();
this.MMEventStartListening<MMFadeOutEvent>();
}
/// <summary>
/// On disable, we stop listening to events
/// </summary>
protected virtual void OnDisable()
{
this.MMEventStopListening<MMFadeEvent>();
this.MMEventStopListening<MMFadeStopEvent>();
this.MMEventStopListening<MMFadeInEvent>();
this.MMEventStopListening<MMFadeOutEvent>();
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: efe052b91c95c534b8bf0f64fb0b9151
timeCreated: 1523969902
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,373 @@
using UnityEngine;
using System.Collections;
using System;
using UnityEngine.UI;
using MoreMountains.Tools;
namespace MoreMountains.Tools
{
/// <summary>
/// The Fader class can be put on an Image, and it'll intercept MMFadeEvents and turn itself on or off accordingly.
/// This specific fader will move from left to right, right to left, top to bottom or bottom to top
/// </summary>
[RequireComponent(typeof(CanvasGroup))]
[AddComponentMenu("More Mountains/Tools/GUI/MMFaderDirectional")]
public class MMFaderDirectional : MonoBehaviour, MMEventListener<MMFadeEvent>, MMEventListener<MMFadeInEvent>, MMEventListener<MMFadeOutEvent>, MMEventListener<MMFadeStopEvent>
{
/// the possible directions this fader can move in
public enum Directions { TopToBottom, LeftToRight, RightToLeft, BottomToTop }
[Header("Identification")]
/// the ID for this fader (0 is default), set more IDs if you need more than one fader
[Tooltip("the ID for this fader (0 is default), set more IDs if you need more than one fader")]
public int ID;
[Header("Directional Fader")]
/// the direction this fader should move in when fading in
[Tooltip("the direction this fader should move in when fading in")]
public Directions FadeInDirection = Directions.LeftToRight;
/// the direction this fader should move in when fading out
[Tooltip("the direction this fader should move in when fading out")]
public Directions FadeOutDirection = Directions.LeftToRight;
[Header("Timing")]
/// the default duration of the fade in/out
[Tooltip("the default duration of the fade in/out")]
public float DefaultDuration = 0.2f;
/// the default curve to use for this fader
[Tooltip("the default curve to use for this fader")]
public MMTweenType DefaultTween = new MMTweenType(MMTween.MMTweenCurve.LinearTween);
/// whether or not the fade should happen in unscaled time
[Tooltip("whether or not the fade should happen in unscaled time")]
public bool IgnoreTimescale = true;
/// whether or not to automatically disable this fader on init
[Tooltip("whether or not to automatically disable this fader on init")]
public bool DisableOnInit = true;
[Header("Delay")]
/// a delay (in seconds) to apply before playing this fade
[Tooltip("a delay (in seconds) to apply before playing this fade")]
public float InitialDelay = 0f;
[Header("Interaction")]
/// whether or not the fader should block raycasts when visible
[Tooltip("whether or not the fader should block raycasts when visible")]
public bool ShouldBlockRaycasts = false;
/// the width of the fader
public virtual float Width { get { return _rectTransform.rect.width; } }
/// the height of the fader
public virtual float Height { get { return _rectTransform.rect.height; } }
[Header("Debug")]
[MMInspectorButton("FadeIn1Second")]
public bool FadeIn1SecondButton;
[MMInspectorButton("FadeOut1Second")]
public bool FadeOut1SecondButton;
[MMInspectorButton("DefaultFade")]
public bool DefaultFadeButton;
[MMInspectorButton("ResetFader")]
public bool ResetFaderButton;
protected RectTransform _rectTransform;
protected CanvasGroup _canvasGroup;
protected float _currentDuration;
protected MMTweenType _currentCurve;
protected bool _fading = false;
protected float _fadeStartedAt;
protected Vector2 _initialPosition;
protected Vector2 _fromPosition;
protected Vector2 _toPosition;
protected Vector2 _newPosition;
protected bool _active;
protected bool _initialized = false;
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void ResetFader()
{
_rectTransform.anchoredPosition = _initialPosition;
}
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void DefaultFade()
{
MMFadeEvent.Trigger(DefaultDuration, 1f, DefaultTween, ID, IgnoreTimescale, this.transform.position);
}
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void FadeIn1Second()
{
MMFadeInEvent.Trigger(1f, DefaultTween, ID, IgnoreTimescale, this.transform.position);
}
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void FadeOut1Second()
{
MMFadeOutEvent.Trigger(1f, DefaultTween, ID, IgnoreTimescale, this.transform.position);
}
/// <summary>
/// On Start, we initialize our fader
/// </summary>
protected virtual void Start()
{
Initialization();
}
/// <summary>
/// On init, we grab our components, and disable/hide everything
/// </summary>
//protected virtual IEnumerator Initialization()
protected virtual void Initialization()
{
_canvasGroup = this.gameObject.GetComponent<CanvasGroup>();
_rectTransform = this.gameObject.GetComponent<RectTransform>();
_initialPosition = _rectTransform.anchoredPosition;
if (DisableOnInit)
{
DisableFader();
}
_initialized = true;
}
/// <summary>
/// On Update, we update our alpha
/// </summary>
protected virtual void Update()
{
if (_canvasGroup == null) { return; }
if (_fading)
{
Fade();
}
}
/// <summary>
/// Fades the canvasgroup towards its target alpha
/// </summary>
protected virtual void Fade()
{
float currentTime = IgnoreTimescale ? Time.unscaledTime : Time.time;
float endTime = _fadeStartedAt + _currentDuration;
if (currentTime - _fadeStartedAt < _currentDuration)
{
_newPosition = MMTween.Tween(currentTime, _fadeStartedAt, endTime, _fromPosition, _toPosition, _currentCurve);
_rectTransform.anchoredPosition = _newPosition;
}
else
{
StopFading();
}
}
/// <summary>
/// Stops the fading.
/// </summary>
protected virtual void StopFading()
{
_rectTransform.anchoredPosition = _toPosition;
_fading = false;
if (_initialPosition != _toPosition)
{
DisableFader();
}
}
/// <summary>
/// Starts a fade
/// </summary>
/// <param name="fadingIn"></param>
/// <param name="duration"></param>
/// <param name="curve"></param>
/// <param name="id"></param>
/// <param name="ignoreTimeScale"></param>
/// <param name="worldPosition"></param>
protected virtual IEnumerator StartFading(bool fadingIn, float duration, MMTweenType curve, int id,
bool ignoreTimeScale, Vector3 worldPosition)
{
if (id != ID)
{
yield break;
}
if (InitialDelay > 0f)
{
yield return MMCoroutine.WaitFor(InitialDelay);
}
if (!_initialized)
{
Initialization();
}
if (curve == null)
{
curve = DefaultTween;
}
IgnoreTimescale = ignoreTimeScale;
EnableFader();
_fading = true;
_fadeStartedAt = IgnoreTimescale ? Time.unscaledTime : Time.time;
_currentCurve = curve;
_currentDuration = duration;
_fromPosition = _rectTransform.anchoredPosition;
_toPosition = fadingIn ? _initialPosition : ExitPosition();
_newPosition = MMTween.Tween(0f, 0f, duration, _fromPosition, _toPosition, _currentCurve);
_rectTransform.anchoredPosition = _newPosition;
}
/// <summary>
/// Determines the position of the fader before entry
/// </summary>
/// <returns></returns>
protected virtual Vector2 BeforeEntryPosition()
{
switch (FadeInDirection)
{
case Directions.BottomToTop:
return _initialPosition + Vector2.down * Height;
case Directions.LeftToRight:
return _initialPosition + Vector2.left * Width;
case Directions.RightToLeft:
return _initialPosition + Vector2.right * Width;
case Directions.TopToBottom:
return _initialPosition + Vector2.up * Height;
}
return Vector2.zero;
}
/// <summary>
/// Determines the exit position of the fader
/// </summary>
/// <returns></returns>
protected virtual Vector2 ExitPosition()
{
switch (FadeOutDirection)
{
case Directions.BottomToTop:
return _initialPosition + Vector2.up * Height;
case Directions.LeftToRight:
return _initialPosition + Vector2.right * Width;
case Directions.RightToLeft:
return _initialPosition + Vector2.left * Width;
case Directions.TopToBottom:
return _initialPosition + Vector2.down * Height;
}
return Vector2.zero;
}
/// <summary>
/// Disables the fader.
/// </summary>
protected virtual void DisableFader()
{
if (ShouldBlockRaycasts)
{
_canvasGroup.blocksRaycasts = false;
}
_active = false;
_canvasGroup.alpha = 0;
_rectTransform.anchoredPosition = BeforeEntryPosition();
this.enabled = false;
}
/// <summary>
/// Enables the fader.
/// </summary>
protected virtual void EnableFader()
{
this.enabled = true;
if (ShouldBlockRaycasts)
{
_canvasGroup.blocksRaycasts = true;
}
_active = true;
_canvasGroup.alpha = 1;
}
/// <summary>
/// When catching a fade event, we fade our image in or out
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeEvent fadeEvent)
{
bool status = _active ? false : true;
StartCoroutine(StartFading(status, fadeEvent.Duration, fadeEvent.Curve, fadeEvent.ID,
fadeEvent.IgnoreTimeScale, fadeEvent.WorldPosition));
}
/// <summary>
/// When catching an MMFadeInEvent, we fade our image in
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeInEvent fadeEvent)
{
StartCoroutine(StartFading(true, fadeEvent.Duration, fadeEvent.Curve, fadeEvent.ID,
fadeEvent.IgnoreTimeScale, fadeEvent.WorldPosition));
}
/// <summary>
/// When catching an MMFadeOutEvent, we fade our image out
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeOutEvent fadeEvent)
{
StartCoroutine(StartFading(false, fadeEvent.Duration, fadeEvent.Curve, fadeEvent.ID,
fadeEvent.IgnoreTimeScale, fadeEvent.WorldPosition));
}
/// <summary>
/// When catching an MMFadeStopEvent, we stop our fade
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeStopEvent fadeStopEvent)
{
if (fadeStopEvent.ID == ID)
{
_fading = false;
if (fadeStopEvent.Restore)
{
_rectTransform.anchoredPosition = _initialPosition;
}
}
}
/// <summary>
/// On enable, we start listening to events
/// </summary>
protected virtual void OnEnable()
{
this.MMEventStartListening<MMFadeEvent>();
this.MMEventStartListening<MMFadeStopEvent>();
this.MMEventStartListening<MMFadeInEvent>();
this.MMEventStartListening<MMFadeOutEvent>();
}
/// <summary>
/// On disable, we stop listening to events
/// </summary>
protected virtual void OnDestroy()
{
this.MMEventStopListening<MMFadeEvent>();
this.MMEventStopListening<MMFadeStopEvent>();
this.MMEventStopListening<MMFadeInEvent>();
this.MMEventStopListening<MMFadeOutEvent>();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 315af83f344d8a24e9f6d1399e439fdd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,308 @@
using UnityEngine;
using System.Collections;
using System;
using UnityEngine.UI;
using MoreMountains.Tools;
namespace MoreMountains.Tools
{
/// <summary>
/// The Fader class can be put on an Image, and it'll intercept MMFadeEvents and turn itself on or off accordingly.
/// </summary>
[RequireComponent(typeof(CanvasGroup))]
[AddComponentMenu("More Mountains/Tools/GUI/MMFaderRound")]
public class MMFaderRound : MonoBehaviour, MMEventListener<MMFadeEvent>, MMEventListener<MMFadeInEvent>, MMEventListener<MMFadeOutEvent>, MMEventListener<MMFadeStopEvent>
{
public enum CameraModes { Main, Override }
[Header("Bindings")]
public CameraModes CameraMode = CameraModes.Main;
[MMEnumCondition("CameraMode",(int)CameraModes.Override)]
/// the camera to pick the position from (usually the "regular" game camera)
public Camera TargetCamera;
/// the background to fade
public RectTransform FaderBackground;
/// the mask used to draw a hole in the background that will get faded / scaled
public RectTransform FaderMask;
[Header("Identification")]
/// the ID for this fader (0 is default), set more IDs if you need more than one fader
public int ID;
[Header("Mask")]
[MMVector("min", "max")]
/// the mask's scale at minimum and maximum opening
public Vector2 MaskScale;
[Header("Timing")]
/// the default duration of the fade in/out
public float DefaultDuration = 0.2f;
/// the default curve to use for this fader
public MMTweenType DefaultTween = new MMTweenType(MMTween.MMTweenCurve.LinearTween);
/// whether or not the fade should happen in unscaled time
public bool IgnoreTimescale = true;
[Header("Interaction")]
/// whether or not the fader should block raycasts when visible
public bool ShouldBlockRaycasts = false;
[Header("Debug")]
public Transform DebugWorldPositionTarget;
[MMInspectorButton("FadeIn1Second")]
public bool FadeIn1SecondButton;
[MMInspectorButton("FadeOut1Second")]
public bool FadeOut1SecondButton;
[MMInspectorButton("DefaultFade")]
public bool DefaultFadeButton;
[MMInspectorButton("ResetFader")]
public bool ResetFaderButton;
protected CanvasGroup _canvasGroup;
protected float _initialScale;
protected float _currentTargetScale;
protected float _currentDuration;
protected MMTweenType _currentCurve;
protected bool _fading = false;
protected float _fadeStartedAt;
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void ResetFader()
{
FaderMask.transform.localScale = MaskScale.x * Vector3.one;
}
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void DefaultFade()
{
MMFadeEvent.Trigger(DefaultDuration, MaskScale.y, DefaultTween, ID, IgnoreTimescale, DebugWorldPositionTarget.transform.position);
}
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void FadeIn1Second()
{
MMFadeInEvent.Trigger(1f, DefaultTween, ID, IgnoreTimescale, DebugWorldPositionTarget.transform.position);
}
/// <summary>
/// Test method triggered by an inspector button
/// </summary>
protected virtual void FadeOut1Second()
{
MMFadeOutEvent.Trigger(1f, DefaultTween, ID, IgnoreTimescale, DebugWorldPositionTarget.transform.position);
}
/// <summary>
/// On Start, we initialize our fader
/// </summary>
protected virtual void Awake()
{
Initialization();
}
/// <summary>
/// On init, we grab our components, and disable/hide everything
/// </summary>
protected virtual void Initialization()
{
if (CameraMode == CameraModes.Main)
{
TargetCamera = Camera.main;
}
_canvasGroup = GetComponent<CanvasGroup>();
FaderMask.transform.localScale = MaskScale.x * Vector3.one;
}
/// <summary>
/// On Update, we update our alpha
/// </summary>
protected virtual void Update()
{
if (_canvasGroup == null) { return; }
if (_fading)
{
Fade();
}
}
/// <summary>
/// Fades the canvasgroup towards its target alpha
/// </summary>
protected virtual void Fade()
{
float currentTime = IgnoreTimescale ? Time.unscaledTime : Time.time;
float endTime = _fadeStartedAt + _currentDuration;
if (currentTime - _fadeStartedAt < _currentDuration)
{
float newScale = MMTween.Tween(currentTime, _fadeStartedAt, endTime, _initialScale, _currentTargetScale, _currentCurve);
FaderMask.transform.localScale = newScale * Vector3.one;
}
else
{
StopFading();
}
}
/// <summary>
/// Stops the fading.
/// </summary>
protected virtual void StopFading()
{
FaderMask.transform.localScale = _currentTargetScale * Vector3.one;
_fading = false;
if (FaderMask.transform.localScale == MaskScale.y * Vector3.one)
{
DisableFader();
}
}
/// <summary>
/// Disables the fader.
/// </summary>
protected virtual void DisableFader()
{
if (ShouldBlockRaycasts)
{
_canvasGroup.blocksRaycasts = false;
}
_canvasGroup.alpha = 0;
}
/// <summary>
/// Enables the fader.
/// </summary>
protected virtual void EnableFader()
{
if (ShouldBlockRaycasts)
{
_canvasGroup.blocksRaycasts = true;
}
_canvasGroup.alpha = 1;
}
protected virtual void StartFading(float initialAlpha, float endAlpha, float duration, MMTweenType curve, int id,
bool ignoreTimeScale, Vector3 worldPosition)
{
if (id != ID)
{
return;
}
if (TargetCamera == null)
{
Debug.LogWarning(this.name + " : You're using a fader round but its TargetCamera hasn't been setup in its inspector. It can't fade.");
return;
}
FaderMask.anchoredPosition = Vector3.zero;
Vector3 viewportPosition = TargetCamera.WorldToViewportPoint(worldPosition);
viewportPosition.x = Mathf.Clamp01(viewportPosition.x);
viewportPosition.y = Mathf.Clamp01(viewportPosition.y);
viewportPosition.z = Mathf.Clamp01(viewportPosition.z);
FaderMask.anchorMin = viewportPosition;
FaderMask.anchorMax = viewportPosition;
IgnoreTimescale = ignoreTimeScale;
EnableFader();
_fading = true;
_initialScale = initialAlpha;
_currentTargetScale = endAlpha;
_fadeStartedAt = IgnoreTimescale ? Time.unscaledTime : Time.time;
_currentCurve = curve;
_currentDuration = duration;
float newScale = MMTween.Tween(0f, 0f, duration, _initialScale, _currentTargetScale, _currentCurve);
FaderMask.transform.localScale = newScale * Vector3.one;
}
/// <summary>
/// When catching a fade event, we fade our image in or out
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeEvent fadeEvent)
{
_currentTargetScale = (fadeEvent.TargetAlpha == -1) ? MaskScale.y : fadeEvent.TargetAlpha;
StartFading(FaderMask.transform.localScale.x, _currentTargetScale, fadeEvent.Duration, fadeEvent.Curve, fadeEvent.ID,
fadeEvent.IgnoreTimeScale, fadeEvent.WorldPosition);
}
/// <summary>
/// When catching an MMFadeInEvent, we fade our image in
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeInEvent fadeEvent)
{
if (fadeEvent.Duration > 0)
{
StartFading(MaskScale.y, MaskScale.x, fadeEvent.Duration, fadeEvent.Curve, fadeEvent.ID,
fadeEvent.IgnoreTimeScale, fadeEvent.WorldPosition);
}
else
{
FaderMask.transform.localScale = MaskScale.x * Vector3.one;
}
}
/// <summary>
/// When catching an MMFadeOutEvent, we fade our image out
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeOutEvent fadeEvent)
{
if (fadeEvent.Duration > 0)
{
StartFading(MaskScale.x, MaskScale.y, fadeEvent.Duration, fadeEvent.Curve, fadeEvent.ID,
fadeEvent.IgnoreTimeScale, fadeEvent.WorldPosition);
}
else
{
FaderMask.transform.localScale = MaskScale.y * Vector3.one;
}
}
/// <summary>
/// When catching an MMFadeStopEvent, we stop our fade
/// </summary>
/// <param name="fadeEvent">Fade event.</param>
public virtual void OnMMEvent(MMFadeStopEvent fadeStopEvent)
{
if (fadeStopEvent.ID == ID)
{
_fading = false;
if (fadeStopEvent.Restore)
{
FaderMask.transform.localScale = _initialScale * Vector3.one;
}
}
}
/// <summary>
/// On enable, we start listening to events
/// </summary>
protected virtual void OnEnable()
{
this.MMEventStartListening<MMFadeEvent>();
this.MMEventStartListening<MMFadeStopEvent>();
this.MMEventStartListening<MMFadeInEvent>();
this.MMEventStartListening<MMFadeOutEvent>();
}
/// <summary>
/// On disable, we stop listening to events
/// </summary>
protected virtual void OnDisable()
{
this.MMEventStopListening<MMFadeEvent>();
this.MMEventStopListening<MMFadeStopEvent>();
this.MMEventStopListening<MMFadeInEvent>();
this.MMEventStopListening<MMFadeOutEvent>();
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: b2691418b0bcfc540b38b297cf91acf2
timeCreated: 1523969902
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using MoreMountains.Tools;
using UnityEngine.EventSystems;
namespace MoreMountains.Tools
{
/// <summary>
/// Add this helper to an object and focus will be set to it on Enable
/// </summary>
[AddComponentMenu("More Mountains/Tools/GUI/MMGetFocusOnEnable")]
public class MMGetFocusOnEnable : MonoBehaviour
{
protected virtual void OnEnable()
{
EventSystem.current.SetSelectedGameObject(this.gameObject, null);
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 4c7437225490c3443b6d19ca7cc00196
timeCreated: 1523894192
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,512 @@
using System;
using UnityEngine;
using MoreMountains.Tools;
using System.Collections;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace MoreMountains.Tools
{
/// <summary>
/// Add this component to an object and it will show a healthbar above it
/// You can either use a prefab for it, or have the component draw one at the start
/// </summary>
[AddComponentMenu("More Mountains/Tools/GUI/MMHealthBar")]
public class MMHealthBar : MonoBehaviour
{
/// the possible health bar types
public enum HealthBarTypes { Prefab, Drawn, Existing }
/// the possible timescales the bar can work on
public enum TimeScales { UnscaledTime, Time }
[MMInformation("Add this component to an object and it'll add a healthbar next to it to reflect its health level in real time. You can decide here whether the health bar should be drawn automatically or use a prefab.",MoreMountains.Tools.MMInformationAttribute.InformationType.Info,false)]
/// whether the healthbar uses a prefab or is drawn automatically
[Tooltip("whether the healthbar uses a prefab or is drawn automatically")]
public HealthBarTypes HealthBarType = HealthBarTypes.Drawn;
/// defines whether the bar will work on scaled or unscaled time (whether or not it'll keep moving if time is slowed down for example)
[Tooltip("defines whether the bar will work on scaled or unscaled time (whether or not it'll keep moving if time is slowed down for example)")]
public TimeScales TimeScale = TimeScales.UnscaledTime;
[Header("Select a Prefab")]
[MMInformation("Select a prefab with a progress bar script on it. There is one example of such a prefab in Common/Prefabs/GUI.",MoreMountains.Tools.MMInformationAttribute.InformationType.Info,false)]
/// the prefab to use as the health bar
[Tooltip("the prefab to use as the health bar")]
public MMProgressBar HealthBarPrefab;
[Header("Existing MMProgressBar")]
/// the MMProgressBar this health bar should update
[Tooltip("the MMProgressBar this health bar should update")]
public MMProgressBar TargetProgressBar;
[Header("Drawn Healthbar Settings ")]
[MMInformation("Set the size (in world units), padding, back and front colors of the healthbar.",MoreMountains.Tools.MMInformationAttribute.InformationType.Info,false)]
/// if the healthbar is drawn, its size in world units
[Tooltip("if the healthbar is drawn, its size in world units")]
public Vector2 Size = new Vector2(1f,0.2f);
/// if the healthbar is drawn, the padding to apply to the foreground, in world units
[Tooltip("if the healthbar is drawn, the padding to apply to the foreground, in world units")]
public Vector2 BackgroundPadding = new Vector2(0.01f,0.01f);
/// the rotation to apply to the MMHealthBarContainer when drawing it
[Tooltip("the rotation to apply to the MMHealthBarContainer when drawing it")]
public Vector3 InitialRotationAngles;
/// if the healthbar is drawn, the color of its foreground
[Tooltip("if the healthbar is drawn, the color of its foreground")]
public Gradient ForegroundColor = new Gradient()
{
colorKeys = new GradientColorKey[2] {
new GradientColorKey(MMColors.BestRed, 0),
new GradientColorKey(MMColors.BestRed, 1f)
},
alphaKeys = new GradientAlphaKey[2] {new GradientAlphaKey(1, 0),new GradientAlphaKey(1, 1)}};
/// if the healthbar is drawn, the color of its delayed bar
[Tooltip("if the healthbar is drawn, the color of its delayed bar")]
public Gradient DelayedColor = new Gradient()
{
colorKeys = new GradientColorKey[2] {
new GradientColorKey(MMColors.Orange, 0),
new GradientColorKey(MMColors.Orange, 1f)
},
alphaKeys = new GradientAlphaKey[2] { new GradientAlphaKey(1, 0), new GradientAlphaKey(1, 1) }
};
/// if the healthbar is drawn, the color of its border
[Tooltip("if the healthbar is drawn, the color of its border")]
public Gradient BorderColor = new Gradient()
{
colorKeys = new GradientColorKey[2] {
new GradientColorKey(MMColors.AntiqueWhite, 0),
new GradientColorKey(MMColors.AntiqueWhite, 1f)
},
alphaKeys = new GradientAlphaKey[2] { new GradientAlphaKey(1, 0), new GradientAlphaKey(1, 1) }
};
/// if the healthbar is drawn, the color of its background
[Tooltip("if the healthbar is drawn, the color of its background")]
public Gradient BackgroundColor = new Gradient()
{
colorKeys = new GradientColorKey[2] {
new GradientColorKey(MMColors.Black, 0),
new GradientColorKey(MMColors.Black, 1f)
},
alphaKeys = new GradientAlphaKey[2] { new GradientAlphaKey(1, 0), new GradientAlphaKey(1, 1) }
};
/// the name of the sorting layer to put this health bar on
[Tooltip("the name of the sorting layer to put this health bar on")]
public string SortingLayerName = "UI";
/// the delay to apply to the delayed bar if drawn
[Tooltip("the delay to apply to the delayed bar if drawn")]
public float Delay = 0.5f;
/// whether or not the front bar should lerp
[Tooltip("whether or not the front bar should lerp")]
public bool LerpFrontBar = true;
/// the speed at which the front bar lerps
[Tooltip("the speed at which the front bar lerps")]
public float LerpFrontBarSpeed = 15f;
/// whether or not the delayed bar should lerp
[Tooltip("whether or not the delayed bar should lerp")]
public bool LerpDelayedBar = true;
/// the speed at which the delayed bar lerps
[Tooltip("the speed at which the delayed bar lerps")]
public float LerpDelayedBarSpeed = 15f;
/// if this is true, bumps the scale of the healthbar when its value changes
[Tooltip("if this is true, bumps the scale of the healthbar when its value changes")]
public bool BumpScaleOnChange = true;
/// the duration of the bump animation
[Tooltip("the duration of the bump animation")]
public float BumpDuration = 0.2f;
/// the animation curve to map the bump animation on
[Tooltip("the animation curve to map the bump animation on")]
public AnimationCurve BumpAnimationCurve = AnimationCurve.Constant(0,1,1);
/// the mode the bar should follow the target in
[Tooltip("the mode the bar should follow the target in")]
public MMFollowTarget.UpdateModes FollowTargetMode = MMFollowTarget.UpdateModes.LateUpdate;
/// if this is true, the drawn health bar will be nested below the MMHealthBar
[Tooltip("if this is true, the drawn health bar will be nested below the MMHealthBar")]
public bool NestDrawnHealthBar = false;
/// if this is true, a MMBillboard component will be added to the progress bar to make sure it always looks towards the camera
[Tooltip("if this is true, a MMBillboard component will be added to the progress bar to make sure it always looks towards the camera")]
public bool Billboard = false;
[Header("Death")]
/// a gameobject (usually a particle system) to instantiate when the healthbar reaches zero
[Tooltip("a gameobject (usually a particle system) to instantiate when the healthbar reaches zero")]
public GameObject InstantiatedOnDeath;
[Header("Offset")]
[MMInformation("Set the offset (in world units), relative to the object's center, to which the health bar will be displayed.",MoreMountains.Tools.MMInformationAttribute.InformationType.Info,false)]
/// the offset to apply to the healthbar compared to the object's center
[Tooltip("the offset to apply to the healthbar compared to the object's center")]
public Vector3 HealthBarOffset = new Vector3(0f,1f,0f);
[Header("Display")]
[MMInformation("Here you can define whether or not the healthbar should always be visible. If not, you can set here how long after a hit it'll remain visible.",MoreMountains.Tools.MMInformationAttribute.InformationType.Info,false)]
/// whether or not the bar should be permanently displayed
[Tooltip("whether or not the bar should be permanently displayed")]
public bool AlwaysVisible = true;
/// the duration (in seconds) during which to display the bar
[Tooltip("the duration (in seconds) during which to display the bar")]
public float DisplayDurationOnHit = 1f;
/// if this is set to true the bar will hide itself when it reaches zero
[Tooltip("if this is set to true the bar will hide itself when it reaches zero")]
public bool HideBarAtZero = true;
/// the delay (in seconds) after which to hide the bar
[Tooltip("the delay (in seconds) after which to hide the bar")]
public float HideBarAtZeroDelay = 1f;
[Header("Test")]
/// a test value to use when pressing the TestUpdateHealth button
[Tooltip("a test value to use when pressing the TestUpdateHealth button")]
public float TestMinHealth = 0f;
/// a test value to use when pressing the TestUpdateHealth button
[Tooltip("a test value to use when pressing the TestUpdateHealth button")]
public float TestMaxHealth = 100f;
/// a test value to use when pressing the TestUpdateHealth button
[Tooltip("a test value to use when pressing the TestUpdateHealth button")]
public float TestCurrentHealth = 25f;
[MMInspectorButton("TestUpdateHealth")]
public bool TestUpdateHealthButton;
protected MMProgressBar _progressBar;
protected MMFollowTarget _followTransform;
protected float _lastShowTimestamp = 0f;
protected bool _showBar = false;
protected Image _backgroundImage = null;
protected Image _borderImage = null;
protected Image _foregroundImage = null;
protected Image _delayedImage = null;
protected bool _finalHideStarted = false;
/// <summary>
/// On Start, creates or sets the health bar up
/// </summary>
protected virtual void Awake()
{
Initialization();
}
/// <summary>
/// On enable, initializes the bar again
/// </summary>
protected void OnEnable()
{
_finalHideStarted = false;
SetInitialActiveState();
}
/// <summary>
/// Forces the bar into its initial active state (hiding it if AlwaysVisible is false)
/// </summary>
public virtual void SetInitialActiveState()
{
if (!AlwaysVisible && (_progressBar != null))
{
ShowBar(false);
}
}
/// <summary>
/// Shows or hides the bar by changing its object's active state
/// </summary>
/// <param name="state"></param>
public virtual void ShowBar(bool state)
{
_progressBar.gameObject.SetActive(state);
}
/// <summary>
/// Whether or not the bar is currently active
/// </summary>
/// <returns></returns>
public virtual bool BarIsShown()
{
return _progressBar.gameObject.activeInHierarchy;
}
/// <summary>
/// Initializes the bar (handles visibility, parenting, initial value
/// </summary>
public virtual void Initialization()
{
_finalHideStarted = false;
if (_progressBar != null)
{
ShowBar(AlwaysVisible);
return;
}
switch (HealthBarType)
{
case HealthBarTypes.Prefab:
if (HealthBarPrefab == null)
{
Debug.LogWarning(this.name + " : the HealthBar has no prefab associated to it, nothing will be displayed.");
return;
}
_progressBar = Instantiate(HealthBarPrefab, transform.position + HealthBarOffset, transform.rotation) as MMProgressBar;
SceneManager.MoveGameObjectToScene(_progressBar.gameObject, this.gameObject.scene);
_progressBar.transform.SetParent(this.transform);
_progressBar.gameObject.name = "HealthBar";
break;
case HealthBarTypes.Drawn:
DrawHealthBar();
UpdateDrawnColors();
break;
case HealthBarTypes.Existing:
_progressBar = TargetProgressBar;
break;
}
if (!AlwaysVisible)
{
ShowBar(false);
}
if (_progressBar != null)
{
_progressBar.SetBar(100f, 0f, 100f);
}
}
/// <summary>
/// Draws the health bar.
/// </summary>
protected virtual void DrawHealthBar()
{
GameObject newGameObject = new GameObject();
SceneManager.MoveGameObjectToScene(newGameObject, this.gameObject.scene);
newGameObject.name = "HealthBar|"+this.gameObject.name;
if (NestDrawnHealthBar)
{
newGameObject.transform.SetParent(this.transform);
}
_progressBar = newGameObject.AddComponent<MMProgressBar>();
_followTransform = newGameObject.AddComponent<MMFollowTarget>();
_followTransform.Offset = HealthBarOffset;
_followTransform.Target = this.transform;
_followTransform.FollowRotation = false;
_followTransform.InterpolatePosition = false;
_followTransform.InterpolateRotation = false;
_followTransform.UpdateMode = FollowTargetMode;
Canvas newCanvas = newGameObject.AddComponent<Canvas>();
newCanvas.renderMode = RenderMode.WorldSpace;
newCanvas.transform.localScale = Vector3.one;
newCanvas.GetComponent<RectTransform>().sizeDelta = Size;
if (!string.IsNullOrEmpty(SortingLayerName))
{
newCanvas.sortingLayerName = SortingLayerName;
}
GameObject container = new GameObject();
container.transform.SetParent(newGameObject.transform);
container.name = "MMProgressBarContainer";
container.transform.localScale = Vector3.one;
GameObject borderImageGameObject = new GameObject();
borderImageGameObject.transform.SetParent(container.transform);
borderImageGameObject.name = "HealthBar Border";
_borderImage = borderImageGameObject.AddComponent<Image>();
_borderImage.transform.position = Vector3.zero;
_borderImage.transform.localScale = Vector3.one;
_borderImage.GetComponent<RectTransform>().sizeDelta = Size;
_borderImage.GetComponent<RectTransform>().anchoredPosition = Vector3.zero;
GameObject bgImageGameObject = new GameObject();
bgImageGameObject.transform.SetParent(container.transform);
bgImageGameObject.name = "HealthBar Background";
_backgroundImage = bgImageGameObject.AddComponent<Image>();
_backgroundImage.transform.position = Vector3.zero;
_backgroundImage.transform.localScale = Vector3.one;
_backgroundImage.GetComponent<RectTransform>().sizeDelta = Size - BackgroundPadding*2;
_backgroundImage.GetComponent<RectTransform>().anchoredPosition = -_backgroundImage.GetComponent<RectTransform>().sizeDelta/2;
_backgroundImage.GetComponent<RectTransform>().pivot = Vector2.zero;
GameObject delayedImageGameObject = new GameObject();
delayedImageGameObject.transform.SetParent(container.transform);
delayedImageGameObject.name = "HealthBar Delayed Foreground";
_delayedImage = delayedImageGameObject.AddComponent<Image>();
_delayedImage.transform.position = Vector3.zero;
_delayedImage.transform.localScale = Vector3.one;
_delayedImage.GetComponent<RectTransform>().sizeDelta = Size - BackgroundPadding*2;
_delayedImage.GetComponent<RectTransform>().anchoredPosition = -_delayedImage.GetComponent<RectTransform>().sizeDelta/2;
_delayedImage.GetComponent<RectTransform>().pivot = Vector2.zero;
GameObject frontImageGameObject = new GameObject();
frontImageGameObject.transform.SetParent(container.transform);
frontImageGameObject.name = "HealthBar Foreground";
_foregroundImage = frontImageGameObject.AddComponent<Image>();
_foregroundImage.transform.position = Vector3.zero;
_foregroundImage.transform.localScale = Vector3.one;
_foregroundImage.color = ForegroundColor.Evaluate(1);
_foregroundImage.GetComponent<RectTransform>().sizeDelta = Size - BackgroundPadding*2;
_foregroundImage.GetComponent<RectTransform>().anchoredPosition = -_foregroundImage.GetComponent<RectTransform>().sizeDelta/2;
_foregroundImage.GetComponent<RectTransform>().pivot = Vector2.zero;
if (Billboard)
{
MMBillboard billboard = _progressBar.gameObject.AddComponent<MMBillboard>();
billboard.NestObject = !NestDrawnHealthBar;
}
_progressBar.LerpDecreasingDelayedBar = LerpDelayedBar;
_progressBar.LerpForegroundBar = LerpFrontBar;
_progressBar.LerpDecreasingDelayedBarSpeed = LerpDelayedBarSpeed;
_progressBar.LerpForegroundBarSpeedIncreasing = LerpFrontBarSpeed;
_progressBar.ForegroundBar = _foregroundImage.transform;
_progressBar.DelayedBarDecreasing = _delayedImage.transform;
_progressBar.DecreasingDelay = Delay;
_progressBar.BumpScaleOnChange = BumpScaleOnChange;
_progressBar.BumpDuration = BumpDuration;
_progressBar.BumpScaleAnimationCurve = BumpAnimationCurve;
_progressBar.TimeScale = (TimeScale == TimeScales.Time) ? MMProgressBar.TimeScales.Time : MMProgressBar.TimeScales.UnscaledTime;
container.transform.localEulerAngles = InitialRotationAngles;
_progressBar.Initialization();
}
/// <summary>
/// On Update, we hide or show our healthbar based on our current status
/// </summary>
protected virtual void Update()
{
if (_progressBar == null)
{
return;
}
if (_finalHideStarted)
{
return;
}
UpdateDrawnColors();
if (AlwaysVisible)
{
return;
}
if (_showBar)
{
ShowBar(true);
float currentTime = (TimeScale == TimeScales.UnscaledTime) ? Time.unscaledTime : Time.time;
if (currentTime - _lastShowTimestamp > DisplayDurationOnHit)
{
_showBar = false;
}
}
else
{
if (BarIsShown())
{
ShowBar(false);
}
}
}
/// <summary>
/// Hides the bar when it reaches zero
/// </summary>
/// <returns>The hide bar.</returns>
protected virtual IEnumerator FinalHideBar()
{
_finalHideStarted = true;
if (InstantiatedOnDeath != null)
{
GameObject instantiatedOnDeath = Instantiate(InstantiatedOnDeath, this.transform.position + HealthBarOffset, this.transform.rotation);
SceneManager.MoveGameObjectToScene(instantiatedOnDeath.gameObject, this.gameObject.scene);
}
if (HideBarAtZeroDelay == 0)
{
_showBar = false;
ShowBar(false);
yield return null;
}
else
{
_progressBar.HideBar(HideBarAtZeroDelay);
}
}
/// <summary>
/// Updates the colors of the different bars
/// </summary>
protected virtual void UpdateDrawnColors()
{
if (HealthBarType != HealthBarTypes.Drawn)
{
return;
}
if (_progressBar.Bumping)
{
return;
}
if (_borderImage != null)
{
_borderImage.color = BorderColor.Evaluate(_progressBar.BarProgress);
}
if (_backgroundImage != null)
{
_backgroundImage.color = BackgroundColor.Evaluate(_progressBar.BarProgress);
}
if (_delayedImage != null)
{
_delayedImage.color = DelayedColor.Evaluate(_progressBar.BarProgress);
}
if (_foregroundImage != null)
{
_foregroundImage.color = ForegroundColor.Evaluate(_progressBar.BarProgress);
}
}
/// <summary>
/// Updates the bar
/// </summary>
/// <param name="currentHealth">Current health.</param>
/// <param name="minHealth">Minimum health.</param>
/// <param name="maxHealth">Max health.</param>
/// <param name="show">Whether or not we should show the bar.</param>
public virtual void UpdateBar(float currentHealth, float minHealth, float maxHealth, bool show)
{
// if the healthbar isn't supposed to be always displayed, we turn it on for the specified duration
if (!AlwaysVisible && show)
{
_showBar = true;
_lastShowTimestamp = (TimeScale == TimeScales.UnscaledTime) ? Time.unscaledTime : Time.time;
}
if (_progressBar != null)
{
_progressBar.UpdateBar(currentHealth, minHealth, maxHealth) ;
if (HideBarAtZero && _progressBar.BarTarget <= 0)
{
StartCoroutine(FinalHideBar());
}
if (BumpScaleOnChange)
{
_progressBar.Bump();
}
}
}
/// <summary>
/// A test method used to update the bar when pressing the TestUpdateHealth button in the inspector
/// </summary>
protected virtual void TestUpdateHealth()
{
UpdateBar(TestCurrentHealth, TestMinHealth, TestMaxHealth, true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8abe6344b7148db4687d3c84e7712904
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,77 @@
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace MoreMountains.Tools
{
/// <summary>
/// A simple helper class you can use to trigger methods on Unity's pointer events
/// Typically used on a UI Image
/// </summary>
public class MMOnPointer : MonoBehaviour, IPointerDownHandler, IPointerEnterHandler, IPointerUpHandler, IPointerExitHandler, IPointerClickHandler
{
[Header("Pointer movement")]
/// an event to trigger when the pointer enters the associated game object
[Tooltip("an event to trigger when the pointer enters the associated game object")]
public UnityEvent PointerEnter;
/// an event to trigger when the pointer exits the associated game object
[Tooltip("an event to trigger when the pointer exits the associated game object")]
public UnityEvent PointerExit;
[Header("Clicks")]
/// an event to trigger when the pointer is pressed down on the associated game object
[Tooltip("an event to trigger when the pointer is pressed down on the associated game object")]
public UnityEvent PointerDown;
/// an event to trigger when the pointer is pressed up on the associated game object
[Tooltip("an event to trigger when the pointer is pressed up on the associated game object")]
public UnityEvent PointerUp;
/// an event to trigger when the pointer is clicked on the associated game object
[Tooltip("an event to trigger when the pointer is clicked on the associated game object")]
public UnityEvent PointerClick;
/// <summary>
/// IPointerEnterHandler implementation
/// </summary>
/// <param name="eventData"></param>
public void OnPointerEnter(PointerEventData eventData)
{
PointerEnter?.Invoke();
}
/// <summary>
/// IPointerExitHandler implementation
/// </summary>
/// <param name="eventData"></param>
public void OnPointerExit(PointerEventData eventData)
{
PointerExit?.Invoke();
}
/// <summary>
/// IPointerDownHandler implementation
/// </summary>
/// <param name="eventData"></param>
public void OnPointerDown(PointerEventData eventData)
{
PointerDown?.Invoke();
}
/// <summary>
/// IPointerUpHandler implementation
/// </summary>
/// <param name="eventData"></param>
public void OnPointerUp(PointerEventData eventData)
{
PointerUp?.Invoke();
}
/// <summary>
/// IPointerClickHandler implementation
/// </summary>
/// <param name="eventData"></param>
public void OnPointerClick(PointerEventData eventData)
{
PointerClick?.Invoke();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4b69e4219f8a33d46b034129f4d3ddea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,130 @@
using UnityEngine;
using System.Collections;
using System;
using UnityEngine.UI;
using MoreMountains.Tools;
using System.Collections.Generic;
namespace MoreMountains.Tools
{
[AddComponentMenu("More Mountains/Tools/GUI/MMPSBToUIConverter")]
public class MMPSBToUIConverter : MonoBehaviour
{
[Header("Target")]
public Canvas TargetCanvas;
public float ScaleFactor = 100f;
public bool ReplicateNesting = false;
[Header("Size")]
public float TargetWidth = 2048;
public float TargetHeight = 1152;
[Header("Conversion")]
[MMInspectorButton("ConvertToCanvas")]
public bool ConvertToCanvasButton;
public Vector3 ChildImageOffset = new Vector3(-1024f, -576f, 0f);
protected Transform _topLevel;
protected Dictionary<Transform, int> _sortingOrders;
public virtual void ConvertToCanvas()
{
Screen.SetResolution((int)TargetWidth, (int)TargetHeight, true);
_sortingOrders = new Dictionary<Transform, int>();
// remove existing canvas if found
foreach (Transform child in TargetCanvas.transform)
{
if (child.name == this.name)
{
child.MMDestroyAllChildren();
DestroyImmediate(child.gameObject);
}
}
// force size on canvas scaler
CanvasScaler canvasScaler = TargetCanvas.GetComponent<CanvasScaler>();
if (canvasScaler != null)
{
canvasScaler.referenceResolution = new Vector2(TargetWidth, TargetHeight);
}
// create a parent in the target canvas
GameObject newRoot = new GameObject(this.name, typeof(RectTransform));
newRoot.transform.SetParent(TargetCanvas.transform);
RectTransform newRootRect = newRoot.GetComponent<RectTransform>();
SetupForStretch(newRootRect);
_topLevel = newRoot.transform;
CreateImageForChildren(this.transform, newRoot.transform);
// apply sorting orders
foreach (KeyValuePair<Transform, int> pair in _sortingOrders)
{
pair.Key.SetSiblingIndex(pair.Value);
}
}
/// <summary>
/// Recursively goes through the children of the specified "root" Transform, and parents them to the specified "parent"
/// </summary>
/// <param name="root"></param>
/// <param name="parent"></param>
protected virtual void CreateImageForChildren(Transform root, Transform parent)
{
foreach (Transform child in root)
{
GameObject imageGO = new GameObject(child.name, typeof(RectTransform));
imageGO.transform.localPosition = ScaleFactor * child.transform.localPosition;
if (ReplicateNesting)
{
imageGO.transform.SetParent(parent);
}
else
{
imageGO.transform.SetParent(_topLevel);
Vector3 newLocalPosition = imageGO.transform.localPosition;
newLocalPosition.x = newLocalPosition.x + TargetWidth / 2f;
imageGO.transform.localPosition = newLocalPosition;
}
SpriteRenderer spriteRenderer = child.gameObject.GetComponent<SpriteRenderer>();
if (spriteRenderer != null)
{
Image image = imageGO.AddComponent<Image>();
image.sprite = spriteRenderer.sprite;
_sortingOrders.Add(image.transform, spriteRenderer.sortingOrder);
image.SetNativeSize();
RectTransform imageGoRect = imageGO.GetComponent<RectTransform>();
Vector3 newPosition = imageGoRect.localPosition;
newPosition += ChildImageOffset;
newPosition.z = 0f;
imageGoRect.localPosition = newPosition;
}
else
{
imageGO.name += " - NODE";
RectTransform imageGoRect = imageGO.GetComponent<RectTransform>();
imageGoRect.sizeDelta = new Vector2(TargetWidth, TargetHeight);
imageGoRect.localPosition = Vector3.zero;
}
imageGO.GetComponent<RectTransform>().localScale = Vector3.one;
CreateImageForChildren(child, imageGO.transform);
}
}
protected virtual void SetupForStretch(RectTransform rect)
{
rect.localPosition = Vector3.zero;
rect.anchorMin = new Vector2(0, 0);
rect.anchorMax = new Vector2(1, 1);
rect.pivot = new Vector2(0.5f, 0.5f);
rect.offsetMin = Vector2.zero;
rect.offsetMax = Vector2.zero;
rect.localScale = Vector3.one;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 886cecdd9d0da7e429a987be6cccf1da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using UnityEngine;
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
using UnityEngine.InputSystem;
#endif
namespace MoreMountains.Tools
{
/// <summary>
/// Use this class to bind a number of UI layers to the movements of a mouse cursor, or a mobile device gyroscope, or even have it be piloted by another script
/// By setting different speed/amplitude values for each of your UI layers, you'll be able to create a nice parallax effect
/// </summary>
public class MMParallaxUI : MonoBehaviour
{
/// <summary>
/// A class used to store layer settings
/// </summary>
[Serializable]
public class ParallaxLayer
{
/// the rect transform for this layer
public RectTransform Rect;
/// the speed at which this layer should move
public float Speed = 2f;
/// the maximum distance this layer can travel from its starting position
public float Amplitude = 50f;
/// the starting position for this layer
[HideInInspector]
public Vector2 StartPosition;
/// if this is false, this layer won't move
public bool Active = true;
}
/// the possible modes used to pilot this parallax rig
public enum Modes { Mouse, Gyroscope, Script }
/// the selected mode for this parallax setup. note that gyroscope mode is only available on mobile devices
public Modes Mode = Modes.Mouse;
/// a multiplier to apply to all layers' amplitudes
public float AmplitudeMultiplier = 1f;
/// a speed multiplier to apply to all layers' speeds
public float SpeedMultiplier = 1f;
/// a list of all the layers to pilot
public List<ParallaxLayer> ParallaxLayers;
protected Vector2 _referencePosition;
protected Vector3 _newPosition;
protected Vector2 _mousePosition;
/// <summary>
/// On Start we initialize our reference position
/// </summary>
protected virtual void Start()
{
Initialization();
}
/// <summary>
/// Initializes the start position of all layers
/// </summary>
public virtual void Initialization()
{
foreach (ParallaxLayer layer in ParallaxLayers)
{
layer.StartPosition = layer.Rect.position;
}
}
/// <summary>
/// On Update, moves all layers according to the selected mode
/// </summary>
protected virtual void Update()
{
MoveLayers();
}
/// <summary>
/// Computes the input data according to the selected mode, and moves the layers accordingly
/// </summary>
protected virtual void MoveLayers()
{
switch (Mode)
{
case Modes.Gyroscope:
_referencePosition = MMGyroscope.CalibratedInputAcceleration;
break;
case Modes.Mouse:
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
_mousePosition = Mouse.current.position.ReadValue();
#else
_mousePosition = Input.mousePosition;
#endif
_referencePosition = Camera.main.ScreenToViewportPoint(_mousePosition);
break;
}
foreach (ParallaxLayer layer in ParallaxLayers)
{
if (layer.Active)
{
_newPosition.x = Mathf.Lerp(layer.Rect.position.x, layer.StartPosition.x + _referencePosition.x * layer.Amplitude * AmplitudeMultiplier, layer.Speed * SpeedMultiplier * Time.deltaTime);
_newPosition.y = Mathf.Lerp(layer.Rect.position.y, layer.StartPosition.y + _referencePosition.y * layer.Amplitude * AmplitudeMultiplier, layer.Speed * SpeedMultiplier * Time.deltaTime);
_newPosition.z = 0;
layer.Rect.position = _newPosition;
}
}
}
/// <summary>
/// Sets a new reference position, to use when in Script mode
/// </summary>
/// <param name="newReferencePosition"></param>
public virtual void SetReferencePosition(Vector3 newReferencePosition)
{
_referencePosition = newReferencePosition;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2852911d573562f4a836903e5c779c94
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,983 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
#if MM_TEXTMESHPRO
using TMPro;
#endif
using UnityEngine.Events;
using UnityEngine.Serialization;
namespace MoreMountains.Tools
{
/// <summary>
/// Add this bar to an object and link it to a bar (possibly the same object the script is on), and you'll be able to resize the bar object based on a current value, located between a min and max value.
/// See the HealthBar.cs script for a use case
/// </summary>
[MMRequiresConstantRepaint]
[AddComponentMenu("More Mountains/Tools/GUI/MMProgressBar")]
public class MMProgressBar : MMMonoBehaviour
{
public enum MMProgressBarStates {Idle, Decreasing, Increasing, InDecreasingDelay, InIncreasingDelay }
/// the possible fill modes
public enum FillModes { LocalScale, FillAmount, Width, Height, Anchor }
/// the possible directions for the fill (for local scale and fill amount only)
public enum BarDirections { LeftToRight, RightToLeft, UpToDown, DownToUp }
/// the possible timescales the bar can work on
public enum TimeScales { UnscaledTime, Time }
/// the possible ways to animate the bar fill
public enum BarFillModes { SpeedBased, FixedDuration }
[MMInspectorGroup("Bindings", true, 10)]
/// optional - the ID of the player associated to this bar
[Tooltip("optional - the ID of the player associated to this bar")]
public string PlayerID;
/// the main, foreground bar
[Tooltip("the main, foreground bar")]
public Transform ForegroundBar;
/// the delayed bar that will show when moving from a value to a new, lower value
[Tooltip("the delayed bar that will show when moving from a value to a new, lower value")]
[FormerlySerializedAs("DelayedBar")]
public Transform DelayedBarDecreasing;
/// the delayed bar that will show when moving from a value to a new, higher value
[Tooltip("the delayed bar that will show when moving from a value to a new, higher value")]
public Transform DelayedBarIncreasing;
[MMInspectorGroup("Fill Settings", true, 11)]
/// the local scale or fillamount value to reach when the value associated to the bar is at 0%
[FormerlySerializedAs("StartValue")]
[Range(0f,1f)]
[Tooltip("the local scale or fillamount value to reach when the value associated to the bar is at 0%")]
public float MinimumBarFillValue = 0f;
/// the local scale or fillamount value to reach when the bar is full
[FormerlySerializedAs("EndValue")]
[Range(0f,1f)]
[Tooltip("the local scale or fillamount value to reach when the bar is full")]
public float MaximumBarFillValue = 1f;
/// whether or not to initialize the value of the bar on start
[Tooltip("whether or not to initialize the value of the bar on start")]
public bool SetInitialFillValueOnStart = false;
/// the initial value of the bar
[MMCondition("SetInitialFillValueOnStart", true)]
[Range(0f,1f)]
[Tooltip("the initial value of the bar")]
public float InitialFillValue = 0f;
/// the direction this bar moves to
[Tooltip("the direction this bar moves to")]
public BarDirections BarDirection = BarDirections.LeftToRight;
/// the foreground bar's fill mode
[Tooltip("the foreground bar's fill mode")]
public FillModes FillMode = FillModes.LocalScale;
/// defines whether the bar will work on scaled or unscaled time (whether or not it'll keep moving if time is slowed down for example)
[Tooltip("defines whether the bar will work on scaled or unscaled time (whether or not it'll keep moving if time is slowed down for example)")]
public TimeScales TimeScale = TimeScales.UnscaledTime;
/// the selected fill animation mode
[Tooltip("the selected fill animation mode")]
public BarFillModes BarFillMode = BarFillModes.SpeedBased;
[MMInspectorGroup("Foreground Bar Settings", true, 12)]
/// whether or not the foreground bar should lerp
[Tooltip("whether or not the foreground bar should lerp")]
public bool LerpForegroundBar = true;
/// the speed at which to lerp the foreground bar
[Tooltip("the speed at which to lerp the foreground bar")]
[MMCondition("LerpForegroundBar", true)]
public float LerpForegroundBarSpeedDecreasing = 15f;
/// the speed at which to lerp the foreground bar if value is increasing
[Tooltip("the speed at which to lerp the foreground bar if value is increasing")]
[FormerlySerializedAs("LerpForegroundBarSpeed")]
[MMCondition("LerpForegroundBar", true)]
public float LerpForegroundBarSpeedIncreasing = 15f;
/// the speed at which to lerp the foreground bar if speed is decreasing
[Tooltip("the speed at which to lerp the foreground bar if speed is decreasing")]
[MMCondition("LerpForegroundBar", true)]
public float LerpForegroundBarDurationDecreasing = 0.2f;
/// the duration each update of the foreground bar should take (only if in fixed duration bar fill mode)
[Tooltip("the duration each update of the foreground bar should take (only if in fixed duration bar fill mode)")]
[MMCondition("LerpForegroundBar", true)]
public float LerpForegroundBarDurationIncreasing = 0.2f;
/// the curve to use when animating the foreground bar fill decreasing
[Tooltip("the curve to use when animating the foreground bar fill decreasing")]
[MMCondition("LerpForegroundBar", true)]
public AnimationCurve LerpForegroundBarCurveDecreasing = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
/// the curve to use when animating the foreground bar fill increasing
[Tooltip("the curve to use when animating the foreground bar fill increasing")]
[MMCondition("LerpForegroundBar", true)]
public AnimationCurve LerpForegroundBarCurveIncreasing = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
[MMInspectorGroup("Delayed Bar Decreasing", true, 13)]
/// the delay before the delayed bar moves (in seconds)
[Tooltip("the delay before the delayed bar moves (in seconds)")]
[FormerlySerializedAs("Delay")]
public float DecreasingDelay = 1f;
/// whether or not the delayed bar's animation should lerp
[Tooltip("whether or not the delayed bar's animation should lerp")]
[FormerlySerializedAs("LerpDelayedBar")]
public bool LerpDecreasingDelayedBar = true;
/// the speed at which to lerp the delayed bar
[Tooltip("the speed at which to lerp the delayed bar")]
[FormerlySerializedAs("LerpDelayedBarSpeed")]
[MMCondition("LerpDecreasingDelayedBar", true)]
public float LerpDecreasingDelayedBarSpeed = 15f;
/// the duration each update of the foreground bar should take (only if in fixed duration bar fill mode)
[Tooltip("the duration each update of the foreground bar should take (only if in fixed duration bar fill mode)")]
[FormerlySerializedAs("LerpDelayedBarDuration")]
[MMCondition("LerpDecreasingDelayedBar", true)]
public float LerpDecreasingDelayedBarDuration = 0.2f;
/// the curve to use when animating the delayed bar fill
[Tooltip("the curve to use when animating the delayed bar fill")]
[FormerlySerializedAs("LerpDelayedBarCurve")]
[MMCondition("LerpDecreasingDelayedBar", true)]
public AnimationCurve LerpDecreasingDelayedBarCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
[MMInspectorGroup("Delayed Bar Increasing", true, 18)]
/// the delay before the delayed bar moves (in seconds)
[Tooltip("the delay before the delayed bar moves (in seconds)")]
public float IncreasingDelay = 1f;
/// whether or not the delayed bar's animation should lerp
[Tooltip("whether or not the delayed bar's animation should lerp")]
public bool LerpIncreasingDelayedBar = true;
/// the speed at which to lerp the delayed bar
[Tooltip("the speed at which to lerp the delayed bar")]
[MMCondition("LerpIncreasingDelayedBar", true)]
public float LerpIncreasingDelayedBarSpeed = 15f;
/// the duration each update of the foreground bar should take (only if in fixed duration bar fill mode)
[Tooltip("the duration each update of the foreground bar should take (only if in fixed duration bar fill mode)")]
[MMCondition("LerpIncreasingDelayedBar", true)]
public float LerpIncreasingDelayedBarDuration = 0.2f;
/// the curve to use when animating the delayed bar fill
[Tooltip("the curve to use when animating the delayed bar fill")]
[MMCondition("LerpIncreasingDelayedBar", true)]
public AnimationCurve LerpIncreasingDelayedBarCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
[MMInspectorGroup("Bump", true, 14)]
/// whether or not the bar should "bump" when changing value
[Tooltip("whether or not the bar should 'bump' when changing value")]
public bool BumpScaleOnChange = true;
/// whether or not the bar should bump when its value increases
[Tooltip("whether or not the bar should bump when its value increases")]
public bool BumpOnIncrease = false;
/// whether or not the bar should bump when its value decreases
[Tooltip("whether or not the bar should bump when its value decreases")]
public bool BumpOnDecrease = false;
/// the duration of the bump animation
[Tooltip("the duration of the bump animation")]
public float BumpDuration = 0.2f;
/// whether or not the bar should flash when bumping
[Tooltip("whether or not the bar should flash when bumping")]
public bool ChangeColorWhenBumping = true;
/// whether or not to store the initial bar color before a bump
[Tooltip("whether or not to store the initial bar color before a bump")]
public bool StoreBarColorOnPlay = true;
/// the color to apply to the bar when bumping
[Tooltip("the color to apply to the bar when bumping")]
[MMCondition("ChangeColorWhenBumping", true)]
public Color BumpColor = Color.white;
/// the curve to map the bump animation on
[Tooltip("the curve to map the bump animation on")]
[FormerlySerializedAs("BumpAnimationCurve")]
public AnimationCurve BumpScaleAnimationCurve = new AnimationCurve(new Keyframe(1, 1), new Keyframe(0.3f, 1.05f), new Keyframe(1, 1));
/// the curve to map the bump animation color animation on
[Tooltip("the curve to map the bump animation color animation on")]
public AnimationCurve BumpColorAnimationCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// if this is true, the BumpIntensityMultiplier curve will be evaluated to apply a multiplier to the bump intensity
[Tooltip("if this is true, the BumpIntensityMultiplier curve will be evaluated to apply a multiplier to the bump intensity")]
public bool ApplyBumpIntensityMultiplier = false;
/// the curve to map the bump's intensity on. x is the delta of the bump, y is the associated multiplier
[Tooltip("the curve to map the bump's intensity on. x is the normalized delta of the bump (from -1:-100% to 1:100%), y is the associated multiplier")]
[MMCondition("ApplyBumpIntensityMultiplier", true)]
public AnimationCurve BumpIntensityMultiplier = new AnimationCurve(new Keyframe(-1, 1), new Keyframe(1, 1));
/// whether or not the bar is bumping right now
public virtual bool Bumping { get; protected set; }
[MMInspectorGroup("Events", true, 16)]
/// an event to trigger every time the bar bumps
[Tooltip("an event to trigger every time the bar bumps")]
public UnityEvent OnBump;
/// an event to trigger every time the bar bumps, with its bump intensity (based on BumpDeltaMultiplier) in parameter
[Tooltip("an event to trigger every time the bar bumps, with its bump intensity (based on BumpDeltaMultiplier) in parameter")]
public UnityEvent<float> OnBumpIntensity;
/// an event to trigger every time the bar starts decreasing
[Tooltip("an event to trigger every time the bar starts decreasing")]
public UnityEvent OnBarMovementDecreasingStart;
/// an event to trigger every time the bar stops decreasing
[Tooltip("an event to trigger every time the bar stops decreasing")]
public UnityEvent OnBarMovementDecreasingStop;
/// an event to trigger every time the bar starts increasing
[Tooltip("an event to trigger every time the bar starts increasing")]
public UnityEvent OnBarMovementIncreasingStart;
/// an event to trigger every time the bar stops increasing
[Tooltip("an event to trigger every time the bar stops increasing")]
public UnityEvent OnBarMovementIncreasingStop;
[MMInspectorGroup("Text", true, 20)]
/// a Text object to update with the bar's value
[Tooltip("a Text object to update with the bar's value")]
public Text PercentageText;
#if MM_TEXTMESHPRO
/// a TMPro text object to update with the bar's value
[Tooltip("a TMPro text object to update with the bar's value")]
public TMP_Text PercentageTextMeshPro;
#endif
/// a prefix to always add to the bar's value display
[Tooltip("a prefix to always add to the bar's value display")]
public string TextPrefix;
/// a suffix to always add to the bar's value display
[Tooltip("a suffix to always add to the bar's value display")]
public string TextSuffix;
/// a value multiplier to always apply to the bar's value when displaying it
[Tooltip("a value multiplier to always apply to the bar's value when displaying it")]
public float TextValueMultiplier = 1f;
/// the format in which the text should display
[Tooltip("the format in which the text should display")]
public string TextFormat = "{000}";
/// whether or not to display the total after the current value
[Tooltip("whether or not to display the total after the current value")]
public bool DisplayTotal = false;
/// if DisplayTotal is true, the separator to put between the current value and the total
[Tooltip("if DisplayTotal is true, the separator to put between the current value and the total")]
[MMCondition("DisplayTotal", true)]
public string TotalSeparator = " / ";
[MMInspectorGroup("Debug", true, 15)]
/// the value the bar will move to if you press the DebugSet button
[Tooltip("the value the bar will move to if you press the DebugSet button")]
[Range(0f, 1f)]
public float DebugNewTargetValue;
[MMInspectorButton("DebugUpdateBar")]
public bool DebugUpdateBarButton;
[MMInspectorButton("DebugSetBar")]
public bool DebugSetBarButton;
[MMInspectorButton("Bump")]
public bool TestBumpButton;
[MMInspectorButton("Plus10Percent")]
public bool Plus10PercentButton;
[MMInspectorButton("Minus10Percent")]
public bool Minus10PercentButton;
[MMInspectorGroup("Debug Read Only", true, 19)]
/// the current progress of the bar, ideally read only
[Tooltip("the current progress of the bar, ideally read only")]
[Range(0f,1f)]
public float BarProgress;
/// the value towards which the bar is currently interpolating, ideally read only
[Tooltip("the value towards which the bar is currently interpolating, ideally read only")]
[Range(0f,1f)]
public float BarTarget;
/// the current progress of the delayed bar increasing
[Tooltip("the current progress of the delayed bar increasing")]
[Range(0f,1f)]
public float DelayedBarIncreasingProgress;
/// the current progress of the delayed bar decreasing
[Tooltip("the current progress of the delayed bar decreasing")]
[Range(0f,1f)]
public float DelayedBarDecreasingProgress;
protected bool _initialized;
protected Vector2 _initialBarSize;
protected Color _initialColor;
protected Vector3 _initialScale;
protected Image _foregroundImage;
protected Image _delayedDecreasingImage;
protected Image _delayedIncreasingImage;
protected Vector3 _targetLocalScale = Vector3.one;
protected float _newPercent;
protected float _percentLastTimeBarWasUpdated;
protected float _lastUpdateTimestamp;
protected float _time;
protected float _deltaTime;
protected int _direction;
protected Coroutine _coroutine;
protected bool _coroutineShouldRun = false;
protected bool _isDelayedBarIncreasingNotNull;
protected bool _isDelayedBarDecreasingNotNull;
protected bool _actualUpdate;
protected Vector2 _anchorVector;
protected float _delayedBarDecreasingProgress;
protected float _delayedBarIncreasingProgress;
protected MMProgressBarStates CurrentState = MMProgressBarStates.Idle;
protected string _updatedText;
protected string _totalText;
protected bool _isForegroundBarNotNull;
protected bool _isForegroundImageNotNull;
protected bool _isPercentageTextNotNull;
protected bool _isPercentageTextMeshProNotNull;
#region PUBLIC_API
/// <summary>
/// Updates the bar's values, using a normalized value
/// </summary>
/// <param name="normalizedValue"></param>
public virtual void UpdateBar01(float normalizedValue)
{
UpdateBar(Mathf.Clamp01(normalizedValue), 0f, 1f);
}
/// <summary>
/// Updates the bar's values based on the specified parameters
/// </summary>
/// <param name="currentValue">Current value.</param>
/// <param name="minValue">Minimum value.</param>
/// <param name="maxValue">Max value.</param>
public virtual void UpdateBar(float currentValue,float minValue,float maxValue)
{
if (!_initialized)
{
Initialization();
}
if (StoreBarColorOnPlay)
{
StoreInitialColor();
}
if (!this.gameObject.activeInHierarchy)
{
this.gameObject.SetActive(true);
}
_newPercent = MMMaths.Remap(currentValue, minValue, maxValue, MinimumBarFillValue, MaximumBarFillValue);
_actualUpdate = (BarTarget != _newPercent);
if (!_actualUpdate)
{
return;
}
if (CurrentState != MMProgressBarStates.Idle)
{
if ((CurrentState == MMProgressBarStates.Decreasing) ||
(CurrentState == MMProgressBarStates.InDecreasingDelay))
{
if (_newPercent >= BarTarget)
{
StopCoroutine(_coroutine);
SetBar01(BarTarget);
}
}
if ((CurrentState == MMProgressBarStates.Increasing) ||
(CurrentState == MMProgressBarStates.InIncreasingDelay))
{
if (_newPercent <= BarTarget)
{
StopCoroutine(_coroutine);
SetBar01(BarTarget);
}
}
}
_percentLastTimeBarWasUpdated = BarProgress;
_delayedBarDecreasingProgress = DelayedBarDecreasingProgress;
_delayedBarIncreasingProgress = DelayedBarIncreasingProgress;
BarTarget = _newPercent;
if ((_newPercent != _percentLastTimeBarWasUpdated) && !Bumping)
{
Bump();
}
DetermineDeltaTime();
_lastUpdateTimestamp = _time;
DetermineDirection();
if (_direction < 0)
{
OnBarMovementDecreasingStart?.Invoke();
}
else
{
OnBarMovementIncreasingStart?.Invoke();
}
if (_coroutine != null)
{
StopCoroutine(_coroutine);
}
_coroutineShouldRun = true;
if (this.gameObject.activeInHierarchy)
{
_coroutine = StartCoroutine(UpdateBarsCo());
}
else
{
SetBar(currentValue, minValue, maxValue);
}
UpdateText();
}
/// <summary>
/// Sets the bar value to the one specified
/// </summary>
/// <param name="currentValue"></param>
/// <param name="minValue"></param>
/// <param name="maxValue"></param>
public virtual void SetBar(float currentValue, float minValue, float maxValue)
{
float newPercent = MMMaths.Remap(currentValue, minValue, maxValue, 0f, 1f);
SetBar01(newPercent);
}
/// <summary>
/// Sets the bar value to the normalized value set in parameter
/// </summary>
/// <param name="newPercent"></param>
public virtual void SetBar01(float newPercent)
{
if (!_initialized)
{
Initialization();
}
newPercent = MMMaths.Remap(newPercent, 0f, 1f, MinimumBarFillValue, MaximumBarFillValue);
BarProgress = newPercent;
DelayedBarDecreasingProgress = newPercent;
DelayedBarIncreasingProgress = newPercent;
//_newPercent = newPercent;
BarTarget = newPercent;
_percentLastTimeBarWasUpdated = newPercent;
_delayedBarDecreasingProgress = DelayedBarDecreasingProgress;
_delayedBarIncreasingProgress = DelayedBarIncreasingProgress;
SetBarInternal(newPercent, ForegroundBar, _foregroundImage, _initialBarSize);
SetBarInternal(newPercent, DelayedBarDecreasing, _delayedDecreasingImage, _initialBarSize);
SetBarInternal(newPercent, DelayedBarIncreasing, _delayedIncreasingImage, _initialBarSize);
UpdateText();
_coroutineShouldRun = false;
CurrentState = MMProgressBarStates.Idle;
}
#endregion PUBLIC_API
#region START
/// <summary>
/// On start we store our image component
/// </summary>
protected virtual void Start()
{
if (!_initialized)
{
Initialization();
}
}
protected virtual void OnEnable()
{
if (!_initialized)
{
return;
}
StoreInitialColor();
}
public virtual void Initialization()
{
BarTarget = -1f;
_isForegroundBarNotNull = ForegroundBar != null;
_isDelayedBarDecreasingNotNull = DelayedBarDecreasing != null;
_isDelayedBarIncreasingNotNull = DelayedBarIncreasing != null;
_isPercentageTextNotNull = PercentageText != null;
#if MM_TEXTMESHPRO
_isPercentageTextMeshProNotNull = PercentageTextMeshPro != null;
#endif
_initialScale = this.transform.localScale;
if (_isForegroundBarNotNull)
{
_foregroundImage = ForegroundBar.GetComponent<Image>();
_isForegroundImageNotNull = _foregroundImage != null;
_initialBarSize = _foregroundImage.rectTransform.sizeDelta;
}
if (_isDelayedBarDecreasingNotNull)
{
_delayedDecreasingImage = DelayedBarDecreasing.GetComponent<Image>();
}
if (_isDelayedBarIncreasingNotNull)
{
_delayedIncreasingImage = DelayedBarIncreasing.GetComponent<Image>();
}
_initialized = true;
StoreInitialColor();
_percentLastTimeBarWasUpdated = BarProgress;
if (SetInitialFillValueOnStart)
{
SetBar01(InitialFillValue);
}
}
protected virtual void StoreInitialColor()
{
if (!Bumping && _isForegroundImageNotNull)
{
_initialColor = _foregroundImage.color;
}
}
#endregion START
#region TESTS
/// <summary>
/// This test method, called via the inspector button of the same name, lets you test what happens when you update the bar to a certain value
/// </summary>
protected virtual void DebugUpdateBar()
{
this.UpdateBar01(DebugNewTargetValue);
}
/// <summary>
/// Test method
/// </summary>
protected virtual void DebugSetBar()
{
this.SetBar01(DebugNewTargetValue);
}
/// <summary>
/// Test method - increases the bar's current value by 10%
/// </summary>
public virtual void Plus10Percent()
{
float newProgress = BarTarget + 0.1f;
newProgress = Mathf.Clamp(newProgress, 0f, 1f);
UpdateBar01(newProgress);
}
/// <summary>
/// Test method - decreases the bar's current value by 10%
/// </summary>
public virtual void Minus10Percent()
{
float newProgress = BarTarget - 0.1f;
newProgress = Mathf.Clamp(newProgress, 0f, 1f);
UpdateBar01(newProgress);
}
/// <summary>
/// Test method - increases the bar's current value by 20%
/// </summary>
public virtual void Plus20Percent()
{
float newProgress = BarTarget + 0.2f;
newProgress = Mathf.Clamp(newProgress, 0f, 1f);
UpdateBar01(newProgress);
}
/// <summary>
/// Test method - decreases the bar's current value by 20%
/// </summary>
public virtual void Minus20Percent()
{
float newProgress = BarTarget - 0.2f;
newProgress = Mathf.Clamp(newProgress, 0f, 1f);
UpdateBar01(newProgress);
}
#endregion TESTS
protected virtual void UpdateText()
{
_updatedText = TextPrefix + (BarTarget * TextValueMultiplier).ToString(TextFormat);
if (DisplayTotal)
{
_updatedText += TotalSeparator + (TextValueMultiplier).ToString(TextFormat);
}
_updatedText += TextSuffix;
if (_isPercentageTextNotNull)
{
PercentageText.text = _updatedText;
}
#if MM_TEXTMESHPRO
if (_isPercentageTextMeshProNotNull)
{
PercentageTextMeshPro.text = _updatedText;
}
#endif
}
/// <summary>
/// On Update we update our bars
/// </summary>
protected virtual IEnumerator UpdateBarsCo()
{
while (_coroutineShouldRun)
{
DetermineDeltaTime();
DetermineDirection();
UpdateBars();
yield return null;
}
CurrentState = MMProgressBarStates.Idle;
yield break;
}
protected virtual void DetermineDeltaTime()
{
_deltaTime = (TimeScale == TimeScales.Time) ? Time.deltaTime : Time.unscaledDeltaTime;
_time = (TimeScale == TimeScales.Time) ? Time.time : Time.unscaledTime;
}
protected virtual void DetermineDirection()
{
_direction = (_newPercent > _percentLastTimeBarWasUpdated) ? 1 : -1;
}
/// <summary>
/// Updates the foreground bar's scale
/// </summary>
protected virtual void UpdateBars()
{
float newFill;
float newFillDelayed;
float t1, t2 = 0f;
// if the value is decreasing
if (_direction < 0)
{
newFill = ComputeNewFill(LerpForegroundBar, LerpForegroundBarSpeedDecreasing, LerpForegroundBarDurationDecreasing, LerpForegroundBarCurveDecreasing, 0f, _percentLastTimeBarWasUpdated, out t1);
SetBarInternal(newFill, ForegroundBar, _foregroundImage, _initialBarSize);
SetBarInternal(newFill, DelayedBarIncreasing, _delayedIncreasingImage, _initialBarSize);
BarProgress = newFill;
DelayedBarIncreasingProgress = newFill;
CurrentState = MMProgressBarStates.Decreasing;
if (_time - _lastUpdateTimestamp > DecreasingDelay)
{
newFillDelayed = ComputeNewFill(LerpDecreasingDelayedBar, LerpDecreasingDelayedBarSpeed, LerpDecreasingDelayedBarDuration, LerpDecreasingDelayedBarCurve, DecreasingDelay,_delayedBarDecreasingProgress, out t2);
SetBarInternal(newFillDelayed, DelayedBarDecreasing, _delayedDecreasingImage, _initialBarSize);
DelayedBarDecreasingProgress = newFillDelayed;
CurrentState = MMProgressBarStates.InDecreasingDelay;
}
}
else // if the value is increasing
{
newFill = ComputeNewFill(LerpForegroundBar, LerpForegroundBarSpeedIncreasing, LerpForegroundBarDurationIncreasing, LerpForegroundBarCurveIncreasing, 0f, _delayedBarIncreasingProgress, out t1);
SetBarInternal(newFill, DelayedBarIncreasing, _delayedIncreasingImage, _initialBarSize);
DelayedBarIncreasingProgress = newFill;
CurrentState = MMProgressBarStates.Increasing;
if (DelayedBarIncreasing == null)
{
newFill = ComputeNewFill(LerpForegroundBar, LerpForegroundBarSpeedIncreasing, LerpForegroundBarDurationIncreasing, LerpForegroundBarCurveIncreasing, 0f, _percentLastTimeBarWasUpdated, out t2);
SetBarInternal(newFill, DelayedBarDecreasing, _delayedDecreasingImage, _initialBarSize);
SetBarInternal(newFill, ForegroundBar, _foregroundImage, _initialBarSize);
BarProgress = newFill;
DelayedBarDecreasingProgress = newFill;
CurrentState = MMProgressBarStates.InDecreasingDelay;
}
else
{
if (_time - _lastUpdateTimestamp > IncreasingDelay)
{
newFillDelayed = ComputeNewFill(LerpIncreasingDelayedBar, LerpForegroundBarSpeedIncreasing, LerpForegroundBarDurationIncreasing, LerpForegroundBarCurveIncreasing, IncreasingDelay, _delayedBarDecreasingProgress, out t2);
SetBarInternal(newFillDelayed, DelayedBarDecreasing, _delayedDecreasingImage, _initialBarSize);
SetBarInternal(newFillDelayed, ForegroundBar, _foregroundImage, _initialBarSize);
BarProgress = newFillDelayed;
DelayedBarDecreasingProgress = newFillDelayed;
CurrentState = MMProgressBarStates.InDecreasingDelay;
}
}
}
if ((t1 >= 1f) && (t2 >= 1f))
{
_coroutineShouldRun = false;
if (_direction > 0)
{
OnBarMovementIncreasingStop?.Invoke();
}
else
{
OnBarMovementDecreasingStop?.Invoke();
}
}
}
protected virtual float ComputeNewFill(bool lerpBar, float barSpeed, float barDuration, AnimationCurve barCurve, float delay, float lastPercent, out float t)
{
float newFill = 0f;
t = 0f;
if (lerpBar)
{
float delta = 0f;
float timeSpent = _time - _lastUpdateTimestamp - delay;
float speed = barSpeed;
if (speed == 0f) { speed = 1f; }
float duration = (BarFillMode == BarFillModes.FixedDuration) ? barDuration : (Mathf.Abs(_newPercent - lastPercent)) / speed;
delta = MMMaths.Remap(timeSpent, 0f, duration, 0f, 1f);
delta = Mathf.Clamp(delta, 0f, 1f);
t = delta;
if (t < 1f)
{
delta = barCurve.Evaluate(delta);
newFill = Mathf.LerpUnclamped(lastPercent, _newPercent, delta);
}
else
{
newFill = _newPercent;
}
}
else
{
newFill = _newPercent;
}
newFill = Mathf.Clamp( newFill, 0f, 1f);
return newFill;
}
protected virtual void SetBarInternal(float newAmount, Transform bar, Image image, Vector2 initialSize)
{
if (bar == null)
{
return;
}
switch (FillMode)
{
case FillModes.LocalScale:
_targetLocalScale = Vector3.one;
switch (BarDirection)
{
case BarDirections.LeftToRight:
_targetLocalScale.x = newAmount;
break;
case BarDirections.RightToLeft:
_targetLocalScale.x = 1f - newAmount;
break;
case BarDirections.DownToUp:
_targetLocalScale.y = newAmount;
break;
case BarDirections.UpToDown:
_targetLocalScale.y = 1f - newAmount;
break;
}
bar.localScale = _targetLocalScale;
break;
case FillModes.Width:
if (image == null)
{
return;
}
float newSizeX = MMMaths.Remap(newAmount, 0f, 1f, 0, initialSize.x);
image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, newSizeX);
break;
case FillModes.Height:
if (image == null)
{
return;
}
float newSizeY = MMMaths.Remap(newAmount, 0f, 1f, 0, initialSize.y);
image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, newSizeY);
break;
case FillModes.FillAmount:
if (image == null)
{
return;
}
image.fillAmount = newAmount;
break;
case FillModes.Anchor:
if (image == null)
{
return;
}
switch (BarDirection)
{
case BarDirections.LeftToRight:
_anchorVector.x = 0f;
_anchorVector.y = 0f;
image.rectTransform.anchorMin = _anchorVector;
_anchorVector.x = newAmount;
_anchorVector.y = 1f;
image.rectTransform.anchorMax = _anchorVector;
break;
case BarDirections.RightToLeft:
_anchorVector.x = newAmount;
_anchorVector.y = 0f;
image.rectTransform.anchorMin = _anchorVector;
_anchorVector.x = 1f;
_anchorVector.y = 1f;
image.rectTransform.anchorMax = _anchorVector;
break;
case BarDirections.DownToUp:
_anchorVector.x = 0f;
_anchorVector.y = 0f;
image.rectTransform.anchorMin = _anchorVector;
_anchorVector.x = 1f;
_anchorVector.y = newAmount;
image.rectTransform.anchorMax = _anchorVector;
break;
case BarDirections.UpToDown:
_anchorVector.x = 0f;
_anchorVector.y = newAmount;
image.rectTransform.anchorMin = _anchorVector;
_anchorVector.x = 1f;
_anchorVector.y = 1f;
image.rectTransform.anchorMax = _anchorVector;
break;
}
break;
}
}
#region Bump
/// <summary>
/// Triggers a camera bump
/// </summary>
public virtual void Bump()
{
float delta = _newPercent - _percentLastTimeBarWasUpdated;
float intensityMultiplier = BumpIntensityMultiplier.Evaluate(delta);
bool shouldBump = false;
if (!_initialized)
{
return;
}
DetermineDirection();
if (BumpOnIncrease && (_direction > 0))
{
shouldBump = true;
}
if (BumpOnDecrease && (_direction < 0))
{
shouldBump = true;
}
if (BumpScaleOnChange)
{
shouldBump = true;
}
if (!shouldBump)
{
return;
}
if (this.gameObject.activeInHierarchy)
{
StartCoroutine(BumpCoroutine(intensityMultiplier));
}
OnBump?.Invoke();
OnBumpIntensity?.Invoke(ApplyBumpIntensityMultiplier ? intensityMultiplier : 1f);
}
/// <summary>
/// A coroutine that (usually quickly) changes the scale of the bar
/// </summary>
/// <returns>The coroutine.</returns>
protected virtual IEnumerator BumpCoroutine(float intensityMultiplier)
{
float journey = 0f;
Bumping = true;
while (journey <= BumpDuration)
{
journey = journey + _deltaTime;
float percent = Mathf.Clamp01(journey / BumpDuration);
float curvePercent = BumpScaleAnimationCurve.Evaluate(percent);
if (ApplyBumpIntensityMultiplier)
{
float multiplier = Mathf.Abs(1f - curvePercent) * intensityMultiplier;
curvePercent = 1 + multiplier;
}
float colorCurvePercent = BumpColorAnimationCurve.Evaluate(percent);
this.transform.localScale = curvePercent * _initialScale;
if (ChangeColorWhenBumping && _isForegroundImageNotNull)
{
_foregroundImage.color = Color.Lerp(_initialColor, BumpColor, colorCurvePercent);
}
yield return null;
}
if (ChangeColorWhenBumping && _isForegroundImageNotNull)
{
_foregroundImage.color = _initialColor;
}
Bumping = false;
yield return null;
}
#endregion Bump
#region ShowHide
/// <summary>
/// A simple method you can call to show the bar (set active true)
/// </summary>
public virtual void ShowBar()
{
this.gameObject.SetActive(true);
}
/// <summary>
/// Hides (SetActive false) the progress bar object, after an optional delay
/// </summary>
/// <param name="delay"></param>
public virtual void HideBar(float delay)
{
if (delay <= 0)
{
this.gameObject.SetActive(false);
}
else if (this.gameObject.activeInHierarchy)
{
StartCoroutine(HideBarCo(delay));
}
}
/// <summary>
/// An internal coroutine used to handle the disabling of the progress bar after a delay
/// </summary>
/// <param name="delay"></param>
/// <returns></returns>
protected virtual IEnumerator HideBarCo(float delay)
{
yield return MMCoroutine.WaitFor(delay);
this.gameObject.SetActive(false);
}
#endregion ShowHide
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 0a42a23ce4f9ed24abde69beacbef2f4
timeCreated: 1523894192
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using MoreMountains.Tools;
namespace MoreMountains.Tools
{
public class MMProgressBarDemoAuto : MonoBehaviour
{
public enum TestModes { Permanent, OneTime }
public TestModes TestMode = TestModes.Permanent;
[MMEnumCondition("TestMode", (int)TestModes.Permanent)]
public float CurrentValue = 0f;
[MMEnumCondition("TestMode", (int)TestModes.Permanent)]
public float MinValue = 0f;
[MMEnumCondition("TestMode", (int)TestModes.Permanent)]
public float MaxValue = 100f;
[MMEnumCondition("TestMode", (int)TestModes.Permanent)]
public float Speed = 1f;
[MMEnumCondition("TestMode", (int)TestModes.OneTime)]
public float OneTimeNewValue;
[MMEnumCondition("TestMode", (int)TestModes.OneTime)]
public float OneTimeMinValue;
[MMEnumCondition("TestMode", (int)TestModes.OneTime)]
public float OneTimeMaxValue;
[MMEnumCondition("TestMode", (int)TestModes.OneTime)]
[MMInspectorButton("OneTime")]
public bool OneTimeButton;
protected float _direction = 1f;
protected MMProgressBar _progressBar;
protected virtual void Start()
{
Initialization ();
}
protected virtual void Initialization()
{
_progressBar = GetComponent<MMProgressBar> ();
}
protected virtual void Update()
{
if (TestMode == TestModes.Permanent)
{
_progressBar.UpdateBar(CurrentValue, MinValue, MaxValue);
CurrentValue += Speed * Time.deltaTime * _direction;
if ((CurrentValue <= MinValue) || (CurrentValue >= MaxValue))
{
_direction *= -1;
}
}
}
protected virtual void OneTime()
{
_progressBar.UpdateBar(OneTimeNewValue, OneTimeMinValue, OneTimeMaxValue);
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 8d6b0cf6d1d21694084a7227b664276e
timeCreated: 1523894192
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,59 @@
using UnityEngine;
using System.Collections;
using MoreMountains.Tools;
using UnityEngine.UI;
namespace MoreMountains.Tools
{
/// <summary>
/// Add this class to a radial image and it'll allow you to control its fill amount
/// This is a legacy class, and it's recommended to use MMProgressBar instead, it'll provide the same functionality
/// (make sure you pick FillAmount as the FillMode)
/// and much more options, such as delayed bars, events, bump, and more!
/// </summary>
[AddComponentMenu("More Mountains/Tools/GUI/MMRadialProgressBar")]
public class MMRadialProgressBar : MonoBehaviour
{
/// the start fill amount value
public float StartValue = 1f;
/// the end goad fill amount value
public float EndValue = 0f;
/// the distance to the start or end value at which the class should start lerping
public float Tolerance = 0.01f;
/// optional - the ID of the player associated to this bar
public string PlayerID;
protected Image _radialImage;
protected float _newPercent;
/// <summary>
/// On awake we grab our Image component
/// </summary>
protected virtual void Awake()
{
_radialImage = GetComponent<Image>();
}
/// <summary>
/// Call this method to update the fill amount based on a currentValue between minValue and maxValue
/// </summary>
/// <param name="currentValue">Current value.</param>
/// <param name="minValue">Minimum value.</param>
/// <param name="maxValue">Max value.</param>
public virtual void UpdateBar(float currentValue,float minValue,float maxValue)
{
_newPercent = MMMaths.Remap(currentValue,minValue,maxValue,StartValue,EndValue);
if (_radialImage == null) { return; }
_radialImage.fillAmount = _newPercent;
if (_radialImage.fillAmount > 1 - Tolerance)
{
_radialImage.fillAmount = 1;
}
if (_radialImage.fillAmount < Tolerance)
{
_radialImage.fillAmount = 0;
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 6875477705097214296780853d481a87
timeCreated: 1523969902
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
namespace MoreMountains.Tools
{
/// <summary>
/// Add this class to a UI object to have it act as a raycast target without needing an Image component
/// </summary>
[AddComponentMenu("More Mountains/Tools/GUI/MMRaycastTarget")]
public class MMRaycastTarget : Graphic
{
public override void SetVerticesDirty() { return; }
public override void SetMaterialDirty() { return; }
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
return;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bf220d92758f9a54bae271726c599936
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace MoreMountains.Tools
{
/// <summary>
/// This component, when added on a Text component, will display the name of the level
/// </summary>
public class MMSceneName : MonoBehaviour
{
protected Text _text;
/// <summary>
/// On Awake, stores the Text component
/// </summary>
protected virtual void Awake()
{
_text = this.gameObject.GetComponent<Text>();
}
/// <summary>
/// On Start, sets the level name
/// </summary>
protected virtual void Start()
{
SetLevelNameText();
}
/// <summary>
/// Assigns the level name to the Text
/// </summary>
public virtual void SetLevelNameText()
{
if (_text != null)
{
_text.text = SceneManager.GetActiveScene().name;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d45db69777541e74c8e5f0f820540601
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
using UnityEngine;
using System.Collections;
using System;
namespace MoreMountains.Tools
{
[SelectionBase]
/// <summary>
/// Add this component to an object and it'll always get selection in scene view, even if you select one of its children
/// </summary>
[AddComponentMenu("More Mountains/Tools/GUI/MMSelectionBase")]
public class MMSelectionBase : MonoBehaviour
{
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 0617763b4190c364093ae8e7b62aea45
timeCreated: 1523894192
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace MoreMountains.Tools
{
/// <summary>
/// Add this class to a UI slider and it'll let you trigger events when the cursor moves past a certain step
/// </summary>
[AddComponentMenu("More Mountains/Tools/GUI/MMSliderStep")]
[RequireComponent(typeof(Slider))]
public class MMSliderStep : MonoBehaviour
{
[Header("Slider Step")]
/// the threshold to trigger steps at
public float StepThreshold = 0.1f;
/// the event to trigger when a step is met
public UnityEvent OnStep;
protected Slider _slider;
protected float _lastStep = 0f;
/// <summary>
/// On enable, starts listening for value change events
/// </summary>
protected virtual void OnEnable()
{
_slider = this.gameObject.GetComponent<Slider>();
_slider.onValueChanged.AddListener(ValueChangeCheck);
}
/// <summary>
/// On disable, stops listening for value change events
/// </summary>
protected virtual void OnDisable()
{
_slider.onValueChanged.RemoveListener(ValueChangeCheck);
}
/// <summary>
/// when a value change is met, we trigger an event
/// </summary>
/// <param name="value"></param>
public virtual void ValueChangeCheck(float value)
{
if (Mathf.Abs(_slider.value - _lastStep) > StepThreshold)
{
_lastStep = _slider.value;
OnStep?.Invoke();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e6b7fc2cafd170f4f8b039b213b568c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,136 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace MoreMountains.Tools
{
/// <summary>
/// This class lets you define an axis on which to flip a "two sided" UI element (made of two separate and usually aligned objects, effectively turning each side on/off everytime the container's scale goes above/below a certain threshold
/// </summary>
[ExecuteAlways]
public class MMTwoSidedUI : MonoBehaviour
{
/// the possible axis on which to flip the double object
public enum Axis { x, y, z }
[Header("Bindings")]
/// the object to consider as the "front" of the two sided element. Will be visible if the scale is above the threshold
public GameObject Front;
/// the object to consider as the "back" of the two sided element. Will be visible if the scale is below the threshold
public GameObject Back;
[Header("Axis")]
/// the axis on which to flip this object
public Axis FlipAxis;
/// the scale threshold at which the flip should occur
public float ScaleThreshold = 0f;
[Header("Events")]
/// an event to invoke on flip
public UnityEvent OnFlip;
[Header("Debug")]
/// whether or not we're in debug mode
public bool DebugMode;
/// the value to apply to the scale when in debug mode
[Range(-1f, 1f)]
public float ScaleValue;
/// whether or not our object is flipped right now
[MMReadOnly]
public bool BackVisible = false;
protected RectTransform _rectTransform;
protected bool _initialized = false;
/// <summary>
/// On Start we initialize our object
/// </summary>
protected virtual void Start()
{
Initialization();
}
/// <summary>
/// On init we grab our rect transform and initialize visibility
/// </summary>
protected virtual void Initialization()
{
_rectTransform = this.gameObject.GetComponent<RectTransform>();
_initialized = true;
float axis = GetScaleValue();
BackVisible = (axis < ScaleThreshold);
Front.SetActive(!BackVisible);
Back.SetActive(BackVisible);
}
/// <summary>
/// On Update we update visibility if needed
/// </summary>
protected virtual void Update()
{
#if UNITY_EDITOR
IfEditor();
#endif
float axis = GetScaleValue();
if ((axis < ScaleThreshold) != BackVisible)
{
Front.SetActive(BackVisible);
Back.SetActive(!BackVisible);
OnFlip?.Invoke();
}
BackVisible = (axis < ScaleThreshold);
}
/// <summary>
/// If in editor, we initialize if needed, and apply the debug scale value if needed
/// </summary>
protected virtual void IfEditor()
{
if (!_initialized)
{
Initialization();
}
if (DebugMode)
{
switch (FlipAxis)
{
case Axis.x:
_rectTransform.localScale = new Vector3(ScaleValue, _rectTransform.localScale.y, _rectTransform.localScale.z);
break;
case Axis.y:
_rectTransform.localScale = new Vector3(_rectTransform.localScale.x, ScaleValue, _rectTransform.localScale.z);
break;
case Axis.z:
_rectTransform.localScale = new Vector3(_rectTransform.localScale.x, _rectTransform.localScale.y, ScaleValue);
break;
}
}
}
/// <summary>
/// Returns the scale of the selected axis
/// </summary>
/// <returns></returns>
protected virtual float GetScaleValue()
{
switch (FlipAxis)
{
case Axis.x:
return _rectTransform.localScale.x;
case Axis.y:
return _rectTransform.localScale.y;
case Axis.z:
return _rectTransform.localScale.z;
}
return 0f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4c4ad5c65605834a8f3d6718580bd06
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,28 @@
using UnityEngine;
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
using UnityEngine.InputSystem;
#endif
namespace MoreMountains.Tools
{
/// <summary>
/// This component will let you have a UI object follow the mouse position
/// </summary>
public class MMUIFollowMouse : MonoBehaviour
{
public virtual Canvas TargetCanvas { get; set; }
protected Vector2 _newPosition;
protected Vector2 _mousePosition;
protected virtual void LateUpdate()
{
#if !ENABLE_INPUT_SYSTEM || ENABLE_LEGACY_INPUT_MANAGER
_mousePosition = Input.mousePosition;
#else
_mousePosition = Mouse.current.position.ReadValue();
#endif
RectTransformUtility.ScreenPointToLocalPointInRectangle(TargetCanvas.transform as RectTransform, _mousePosition, TargetCanvas.worldCamera, out _newPosition);
transform.position = TargetCanvas.transform.TransformPoint(_newPosition);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 245a91b1a8b30dc479ea9c354ba36cb8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a4d3807e6b23e624b8fab3d72a31e3c2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: MMFaderRoundMaterialMask
m_Shader: {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords: UNITY_UI_ALPHACLIP
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _ColorMask: 0
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Stencil: 1
- _StencilComp: 8
- _StencilOp: 2
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UVSec: 0
- _UseUIAlphaClip: 1
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d9497e52f2de0254eaec18ccb13d788f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: MMFaderRoundMaterialMasked
m_Shader: {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _ColorMask: 15
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Stencil: 2
- _StencilComp: 3
- _StencilOp: 0
- _StencilReadMask: 1
- _StencilWriteMask: 0
- _UVSec: 0
- _UseUIAlphaClip: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0, g: 0, b: 0, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1297af1e1808f5a48b35411d71934370
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
using UnityEngine;
using System.Collections;
using System;
namespace MoreMountains.Tools
{
[SelectionBase]
/// <summary>
/// Add this component to an object and it'll always get selection in scene view, even if you select one of its children
/// </summary>
[AddComponentMenu("More Mountains/Tools/GUI/SelectionBase")]
public class SelectionBase : MonoBehaviour
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ca4c1ca8bc423b748983b24393521cb7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0e4f009781db7b2448c6cc133802cecf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,147 @@
fileFormatVersion: 2
guid: 47332880f10dee4429534303790a8399
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 1
cookieLightType: 1
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 1024
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 1024
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 1024
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 1024
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 1024
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 1cf89cd354fd1624b96d70e690de2f01
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 909 B

View File

@@ -0,0 +1,135 @@
fileFormatVersion: 2
guid: aff4855d499cb7646b344323f4129b58
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 1
cookieLightType: 1
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant: