using UnityEngine; using System.Collections; using System; using UnityEngine.UI; using MoreMountains.Tools; namespace MoreMountains.Tools { /// /// The Fader class can be put on an Image, and it'll intercept MMFadeEvents and turn itself on or off accordingly. /// [RequireComponent(typeof(CanvasGroup))] [AddComponentMenu("More Mountains/Tools/GUI/MMFaderRound")] public class MMFaderRound : MonoBehaviour, MMEventListener, MMEventListener, MMEventListener, MMEventListener { 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; /// /// Test method triggered by an inspector button /// protected virtual void ResetFader() { FaderMask.transform.localScale = MaskScale.x * Vector3.one; } /// /// Test method triggered by an inspector button /// protected virtual void DefaultFade() { MMFadeEvent.Trigger(DefaultDuration, MaskScale.y, DefaultTween, ID, IgnoreTimescale, DebugWorldPositionTarget.transform.position); } /// /// Test method triggered by an inspector button /// protected virtual void FadeIn1Second() { MMFadeInEvent.Trigger(1f, DefaultTween, ID, IgnoreTimescale, DebugWorldPositionTarget.transform.position); } /// /// Test method triggered by an inspector button /// protected virtual void FadeOut1Second() { MMFadeOutEvent.Trigger(1f, DefaultTween, ID, IgnoreTimescale, DebugWorldPositionTarget.transform.position); } /// /// On Start, we initialize our fader /// protected virtual void Awake() { Initialization(); } /// /// On init, we grab our components, and disable/hide everything /// protected virtual void Initialization() { if (CameraMode == CameraModes.Main) { TargetCamera = Camera.main; } _canvasGroup = GetComponent(); FaderMask.transform.localScale = MaskScale.x * Vector3.one; } /// /// On Update, we update our alpha /// protected virtual void Update() { if (_canvasGroup == null) { return; } if (_fading) { Fade(); } } /// /// Fades the canvasgroup towards its target alpha /// 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(); } } /// /// Stops the fading. /// protected virtual void StopFading() { FaderMask.transform.localScale = _currentTargetScale * Vector3.one; _fading = false; if (FaderMask.transform.localScale == MaskScale.y * Vector3.one) { DisableFader(); } } /// /// Disables the fader. /// protected virtual void DisableFader() { if (ShouldBlockRaycasts) { _canvasGroup.blocksRaycasts = false; } _canvasGroup.alpha = 0; } /// /// Enables the fader. /// 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; } /// /// When catching a fade event, we fade our image in or out /// /// Fade event. 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); } /// /// When catching an MMFadeInEvent, we fade our image in /// /// Fade event. 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; } } /// /// When catching an MMFadeOutEvent, we fade our image out /// /// Fade event. 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; } } /// /// When catching an MMFadeStopEvent, we stop our fade /// /// Fade event. public virtual void OnMMEvent(MMFadeStopEvent fadeStopEvent) { if (fadeStopEvent.ID == ID) { _fading = false; if (fadeStopEvent.Restore) { FaderMask.transform.localScale = _initialScale * Vector3.one; } } } /// /// On enable, we start listening to events /// protected virtual void OnEnable() { this.MMEventStartListening(); this.MMEventStartListening(); this.MMEventStartListening(); this.MMEventStartListening(); } /// /// On disable, we stop listening to events /// protected virtual void OnDisable() { this.MMEventStopListening(); this.MMEventStopListening(); this.MMEventStopListening(); this.MMEventStopListening(); } } }