/// <summary> /// Get's the ease float based on the motion type selected. /// </summary> /// <param name="t">Time (0 to 1).</param> /// <param name="type">Motion Type.</param> /// <param name="parameters">Desired ease function parameters.</param> /// <returns></returns> public static float GetEaseFloat(float t, MotionType type, EasingEquationsParameters p) { float ease = 0; switch (type) { case MotionType.Custom: ease = Custom(t, p.Custom.Curve); break; case MotionType.Linear: ease = Linear(t); break; case MotionType.EaseIn: ease = EaseIn(t, p.EaseIn.EasingPower); break; case MotionType.EaseOut: ease = EaseOut(t, p.EaseOut.EasingPower); break; case MotionType.EaseInOut: ease = EaseInOut(t, p.EaseInOut.EasingPower); break; case MotionType.EaseInElastic: ease = EaseInElastic(t, p.EaseInElastic.ElasticityPower); break; case MotionType.EaseOutElastic: ease = EaseOutElastic(t, p.EaseOutElastic.ElasticityPower); break; case MotionType.EaseInOutElastic: ease = EaseInOutElastic(t, p.EaseInOutElastic.ElasticityPower); break; case MotionType.EaseInBounce: ease = EaseInBounce(t); break; case MotionType.EaseOutBounce: ease = EaseOutBounce(t); break; case MotionType.EaseInOutBounce: ease = EaseInOutBounce(t); break; } return(ease); }
/// <summary> /// Play scale animation /// </summary> /// <param name="visible"></param> /// <param name="motionType"></param> /// <param name="scale"></param> /// <param name="duration"></param> public void ControlScale(bool visible, MotionType motionType, Vector3 scale, float duration, EasingEquationsParameters easingParams, bool instantStart = false) { Vector3 eScale = visible ? ScaleSection.startVectorValue : scale; Vector3 sScale = myRT.localScale; //If the GameObject isn't active then we can't play co-routines so change it instantly. if (!gameObject.activeInHierarchy) { myRT.localScale = eScale; return; } if (ScaleSection.motionEnum != null) { StopCoroutine(ScaleSection.motionEnum); } ScaleSection.motionEnum = VectorMotion((v) => { myRT.localScale = v; }, sScale, eScale, ScaleSection.HideAfter, ScaleSection.ShowAfter, duration, easingParams, motionType, instantStart); StartCoroutine(ScaleSection.motionEnum); }
/// <summary> /// Play opacity animation /// </summary> /// <param name="visible"></param> /// <param name="motionType"></param> /// <param name="opac"></param> /// <param name="duration"></param> public void ControlOpacity(bool visible, MotionType motionType, float opac, float duration, EasingEquationsParameters easingParams, bool instantStart = false) { if (!TargetFader) { FindTargetFader(); } if (!TargetFader) { return; } float eOpacity = visible ? OpacitySection.startFloatValue : opac; float sOpacity = 0; //If the GameObject isn't active then we can't play co-routines so change it instantly. if (!gameObject.activeInHierarchy) { if (TargetFader is Graphic) { Graphic tf = TargetFader as Graphic; Color col = tf.color; col.a = eOpacity; tf.color = col; } else if (TargetFader is CanvasGroup) { CanvasGroup tf = TargetFader as CanvasGroup; tf.alpha = eOpacity; } return; } if (TargetFader is Graphic) { Graphic tf = TargetFader as Graphic; sOpacity = tf.color.a; } else if (TargetFader is CanvasGroup) { CanvasGroup tf = TargetFader as CanvasGroup; sOpacity = tf.alpha; } if (OpacitySection.motionEnum != null) { StopCoroutine(OpacitySection.motionEnum); } OpacitySection.motionEnum = FloatMotion((f) => { if (TargetFader is Graphic) { Graphic tf = TargetFader as Graphic; Color col = tf.color; col.a = f; tf.color = col; } else if (TargetFader is CanvasGroup) { CanvasGroup tf = TargetFader as CanvasGroup; tf.alpha = f; } }, sOpacity, eOpacity, OpacitySection.HideAfter, OpacitySection.ShowAfter, duration, easingParams, motionType, instantStart); StartCoroutine(OpacitySection.motionEnum); }
/// <summary> /// Play rotation animation. /// </summary> /// <param name="visible"></param> /// <param name="motionType"></param> /// <param name="euler"></param> /// <param name="duration"></param> public void ControlRotation(bool visible, MotionType motionType, RotationDirection direction, Vector3 euler, float duration, EasingEquationsParameters easingParams, bool instantStart = false) { euler = ClampAngleVector(euler); Vector3 eEuler = visible ? RotationSection.startVectorValue : euler; Vector3 sEuler = myRT.eulerAngles; //Control rotating direction if (eEuler.z > sEuler.z) { if (direction == RotationDirection.ClockWise) { eEuler -= new Vector3(eEuler.x > 0 ? 360 : 0, eEuler.y > 0 ? 360 : 0, eEuler.z > 0 ? 360 : 0); } } else { if (direction == RotationDirection.AntiClockWise) { sEuler -= new Vector3(sEuler.x > 0 ? 360 : 0, sEuler.y > 0 ? 360 : 0, sEuler.z > 0 ? 360 : 0); } } //If the GameObject isn't active then we can't play co-routines so change it instantly. if (!gameObject.activeInHierarchy) { myRT.eulerAngles = eEuler; return; } if (RotationSection.motionEnum != null) { StopCoroutine(RotationSection.motionEnum); } RotationSection.motionEnum = VectorMotion((v) => { myRT.eulerAngles = v; }, sEuler, eEuler, RotationSection.HideAfter, RotationSection.ShowAfter, duration, easingParams, motionType, instantStart); StartCoroutine(RotationSection.motionEnum); }
/// <summary> /// Play movement animation. /// </summary> /// <param name="visible"></param> /// <param name="motionType"></param> /// <param name="side"></param> /// <param name="duration"></param> /// <param name="bouncesCount"></param> /// <param name="bouncePower"></param> public void ControlMovement(bool visible, MotionType motionType, ScreenSides side, float duration, EasingEquationsParameters easingParams, float edgeGap = 0.25f, bool instantStart = false, Vector3 customPosition = new Vector3(), bool customLocal = false) { Vector3 outPos = outOfScreenPos; if (side != HidingPosition || edgeGap != EdgeGap || (side == ScreenSides.Custom && customLocal != LocalCustomPosition)) { outPos = GetHidingPosition(side, edgeGap, customPosition, customLocal); } Vector3 ePos = visible ? MovementSection.startVectorValue : outPos; Vector3 sPos = myRT.position; //If the GameObject isn't active then we can't play co-routines so change it instantly. if (!gameObject.activeInHierarchy) { myRT.position = ePos; return; } if (MovementSection.motionEnum != null) { StopCoroutine(MovementSection.motionEnum); } MovementSection.motionEnum = VectorMotion((v) => { myRT.position = v; }, sPos, ePos, MovementSection.HideAfter, MovementSection.ShowAfter, duration, easingParams, motionType, instantStart); StartCoroutine(MovementSection.motionEnum); }
/// <summary> /// Change the visibilty of the object by playing the desired animation. /// </summary> /// <param name="visible">Should this element be visible?</param> /// <param name="trivial">If true, sounds won't play and events won't fire</param> public override void ChangeVisibility(bool visible, bool trivial = false) { forceVisibilityCall = true; if (!Initialized) { Initialize(); } //If this GameObject is not active, then change to the desired visibility immediatly and enable it. if (!gameObject.activeSelf) { ChangeVisibilityImmediate(Visible); gameObject.SetActive(true); } //If there's a change in visibility, then play the sound clips. (to avoid playing them if the element is already at the desired visibility when a new call is made) if (Visible != visible && !trivial) { if (SFXManager.Instance) { if (soundEnum != null) { StopCoroutine(soundEnum); } if (visible) { soundEnum = PlaySoundAfter(ShowingClip, ShowAfter); } else { soundEnum = PlaySoundAfter(HidingClip, HideAfter); } //Since coroutines can only start on active objects, then don't try starting them if the object isn't active. if (gameObject.activeInHierarchy) { StartCoroutine(soundEnum); } } else if (ShowingClip || HidingClip) { Debug.LogError("You're trying to play sounds with no SFXManager in the scene. Please add one via Tools>ZUI>Creation Window...>Setup", gameObject); } } Visible = visible; #region Events Handling if (!trivial) { if (startEventEnum != null) { StopCoroutine(startEventEnum); } if (completeEventEnum != null) { StopCoroutine(completeEventEnum); } if (visible) { if (OnShow != null) { startEventEnum = FireEventAfter(OnShow, ShowAfter); } if (OnShowComplete != null) { completeEventEnum = FireEventAfter(OnShowComplete, showingTime); } } else if (!visible) { if (OnHide != null) { startEventEnum = FireEventAfter(OnHide, HideAfter); } //Only start waiting to fire the hide complete event if the element will not deactivate (because if it's deactivated before firing then the event won't fire).. //...and fire it in DeactivateMe function instead if (OnHideComplete != null && !DeactivateWhileInvisible) { completeEventEnum = FireEventAfter(OnHideComplete, hidingTime); } } //Since coroutines can only start on active objects, then don't try starting them if the object isn't active. if (gameObject.activeInHierarchy) { StartCoroutine(startEventEnum); StartCoroutine(completeEventEnum); } } #endregion //If this element is set to use simple activation (enabling and disabling the gameObject) then do it and get out of the function. if (UseSimpleActivation) { ControlActivation(visible); if (visible && OnShow != null) { OnShow.Invoke(); } else if (!visible && OnHide != null) { OnHide.Invoke(); } return; } if (MovementSection.UseSection) { #region Movement Control MotionType type = GetSectionType(MovementSection); float duration = GetSectionDuration(MovementSection); EasingEquationsParameters easingParams = GetEasingParams(MovementSection); ControlMovement(visible, type, HidingPosition, duration, easingParams, EdgeGap, false, MovementSection.WantedVectorValue, LocalCustomPosition); #endregion } if (RotationSection.UseSection) { #region Rotation Control MotionType type = GetSectionType(RotationSection); float duration = GetSectionDuration(RotationSection); EasingEquationsParameters easingParams = GetEasingParams(RotationSection); ControlRotation(visible, type, visible ? ShowingDirection : HidingDirection, RotationSection.WantedVectorValue, duration, easingParams, false); #endregion } if (ScaleSection.UseSection) { #region Scale Control MotionType type = GetSectionType(ScaleSection); float duration = GetSectionDuration(ScaleSection); EasingEquationsParameters easingParams = GetEasingParams(ScaleSection); ControlScale(visible, type, ScaleSection.WantedVectorValue, duration, easingParams, false); #endregion } if (OpacitySection.UseSection) { #region Opacity Control MotionType type = GetSectionType(OpacitySection); float duration = GetSectionDuration(OpacitySection); EasingEquationsParameters easingParams = GetEasingParams(OpacitySection); ControlOpacity(visible, type, OpacitySection.WantedFloatValue, duration, easingParams, false); #endregion } if (SliceSection.UseSection) { #region Slice Control MotionType type = GetSectionType(SliceSection); float duration = GetSectionDuration(SliceSection); EasingEquationsParameters easingParams = GetEasingParams(SliceSection); ControlSlice(visible, type, SliceSection.WantedFloatValue, duration, easingParams, false); #endregion } //If set to deactivate while invisible, then wait until the total hiding time passes and deactivate. if (DeactivateWhileInvisible) { if (!visible) { Invoke("DeactivateMe", hidingTime); } else { CancelInvoke("DeactivateMe"); } } }
IEnumerator FloatMotion(UnityAction <float> output, float start, float end, float sectionHideAfter, float sectionShowAfter, float duration, EasingEquationsParameters easingParams, MotionType motionType, bool instantStart = false) { if (!instantStart && Time.timeScale != 0) { float startAfter = Visible ? (sectionShowAfter < 0 ? ShowAfter : sectionShowAfter) : (sectionHideAfter < 0 ? HideAfter : sectionHideAfter); yield return(new WaitForSeconds(startAfter)); } float curTime = UseUnscaledTime ? Time.unscaledTime : Time.time; float startTime = curTime; while (curTime < startTime + duration) { float t = (curTime - startTime) / duration; float ease = ZUIEquations.GetEaseFloat(t, motionType, easingParams); output(UnClampedLerp(start, end, ease)); yield return(null); curTime = UseUnscaledTime ? Time.unscaledTime : Time.time; } output(end); }
/// <summary> /// Play slicing animation /// </summary> /// <param name="visible"></param> /// <param name="motionType"></param> /// <param name="fill"></param> /// <param name="duration"></param> public void ControlSlice(bool visible, MotionType motionType, float fill, float duration, EasingEquationsParameters easingParams, bool instantStart = false) { if (!SliceImage) { FindSliceImage(); } if (!SliceImage) { return; } float eFill = visible ? SliceSection.startFloatValue : fill; float sFill = 0; //If the GameObject isn't active then we can't play co-routines so change it instantly. if (!gameObject.activeInHierarchy) { SliceImage.fillAmount = eFill; return; } sFill = SliceImage.fillAmount; if (SliceSection.motionEnum != null) { StopCoroutine(SliceSection.motionEnum); } SliceSection.motionEnum = FloatMotion((f) => { SliceImage.fillAmount = f; }, sFill, eFill, SliceSection.HideAfter, SliceSection.ShowAfter, duration, easingParams, motionType, instantStart); StartCoroutine(SliceSection.motionEnum); }