Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections;
using Basis.BTween;
using UnityEngine;
using UnityEngine.UI;

Expand All @@ -16,21 +16,19 @@ public static class Styles
public RectTransform ToggleVisual;

[Header("Visual Elements")]
public Graphic Background; // <= ADD THIS (Image or any UI Graphic)

public Graphic Background;
[Min(0)] public float ToggleVisualOffset = 20f;

[Header("Tween Settings")]
[Min(0)] public float TweenDuration = 0.2f;
public AnimationCurve EaseCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);

[Header("Color Settings")] // <= NICE INSPECTOR BLOCK
public Color OffColor = new Color(0.4f, 0.4f, 0.4f, 1f);
public Color OnColor = new Color(0.2f, 0.8f, 0.4f, 1f);
private TweenAnchorPosition _toggleTween;
private TweenGraphicColor _backgroundTween;

private Coroutine _tweenRoutine;
private bool _initialized;


private PanelToggle() { }

public static PanelToggle CreateNew(Component parent) =>
Expand Down Expand Up @@ -62,76 +60,42 @@ protected override void ApplyValue()
base.ApplyValue();

float targetX = Value ? ToggleVisualOffset : -ToggleVisualOffset;
Color targetColor = Value ? OnColor : OffColor;

if (!Application.isPlaying || !_initialized || TweenDuration <= 0f)
{
SetVisualInstant(Value);
return;
}

if (_tweenRoutine != null)
StopCoroutine(_tweenRoutine);

_tweenRoutine = StartCoroutine(TweenToX(targetX, Value));
}

private void SetVisualInstant(bool on)
{
if (ToggleVisual != null)
if (ToggleVisual)
{
float x = on ? ToggleVisualOffset : -ToggleVisualOffset;
var pos = ToggleVisual.anchoredPosition;
ToggleVisual.anchoredPosition = new Vector2(x, pos.y);
if (_toggleTween && _toggleTween.Active) _toggleTween.Finish();
_toggleTween = ToggleVisual.TweenAnchorPosition(TweenDuration, new Vector2(targetX, 0));
}

if (Background != null)
if (Background)
{
Background.color = on ? OnColor : OffColor;
if (_backgroundTween && _backgroundTween.Active) _backgroundTween.Finish();
_backgroundTween = Background.TweenColor(TweenDuration, Background.color, targetColor);
}
}

private IEnumerator TweenToX(float targetX, bool turningOn)
private void SetVisualInstant(bool on)
{
if (ToggleVisual == null && Background == null)
yield break;

Vector2 startPos = ToggleVisual ? ToggleVisual.anchoredPosition : Vector2.zero;
float startX = startPos.x;
float y = startPos.y;

Color startColor = Background ? Background.color : Color.white;
Color targetColor = turningOn ? OnColor : OffColor;

float time = 0f;

while (time < TweenDuration)
if (ToggleVisual)
{
time += Time.unscaledDeltaTime;
float t = Mathf.Clamp01(time / TweenDuration);

float eased = EaseCurve != null ? EaseCurve.Evaluate(t) : t;

if (ToggleVisual != null)
{
float x = Mathf.Lerp(startX, targetX, eased);
ToggleVisual.anchoredPosition = new Vector2(x, y);
}

if (Background != null)
{
Background.color = Color.Lerp(startColor, targetColor, eased);
}

yield return null;
float x = on ? ToggleVisualOffset : -ToggleVisualOffset;
Vector2 pos = ToggleVisual.anchoredPosition;
ToggleVisual.anchoredPosition = new Vector2(x, pos.y);
}

if (ToggleVisual != null)
ToggleVisual.anchoredPosition = new Vector2(targetX, y);

if (Background != null)
Background.color = targetColor;

_tweenRoutine = null;
if (Background)
{
Background.color = on ? OnColor : OffColor;
}
}
}
}
8 changes: 8 additions & 0 deletions Basis/Packages/com.basis.framework/BasisUI/Tweening.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using UnityEngine;

namespace Basis.BTween
{
public class BTweenManager : MonoBehaviour
{
public static BTweenManager Instance
{
get
{
if (!_instance) AssignInstance();
return _instance;
}
}
private static BTweenManager _instance;

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
private static void AssignInstance()
{
_instance = FindAnyObjectByType<BTweenManager>(FindObjectsInactive.Include);
if (_instance) return;
GameObject obj = new(nameof(BTweenManager));
_instance = obj.AddComponent<BTweenManager>();
}

private void Awake()
{
if (_instance)
{
if (_instance != this)
{
Destroy(gameObject);
return;
}
}
else
{
_instance = this;
DontDestroyOnLoad(this);
}
}

private const int MAX_GROUP_COUNT = 16;
private static readonly List<Action<float>> _tweenProcessors = new(MAX_GROUP_COUNT);

internal static void RegisterGroup(Action<float> processor)
{
if (processor == null) return;
if (_tweenProcessors.Contains(processor)) return;
_tweenProcessors.Add(processor);
}

private static void ProcessAll()
{
float currentTime = Time.realtimeSinceStartup;
List<Action<float>> processors = _tweenProcessors;
foreach (Action<float> tween in processors)
{
tween(currentTime);
}
}

private void Update()
{
ProcessAll();
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

157 changes: 157 additions & 0 deletions Basis/Packages/com.basis.framework/BasisUI/Tweening/EaseTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Largely based on the work of https://easings.net/#

using UnityEngine;

namespace Basis.BTween
{
public enum Easing
{
InSine,
OutSine,
InOutSine,
InQuad,
OutQuad,
InOutQuad,
InCubic,
OutCubic,
InOutCubic,
InQuart,
OutQuart,
InOutQuart,
InQuint,
OutQuint,
InOutQuint,
InExpo,
OutExpo,
InOutExpo,
InCirc,
OutCirc,
InOutCirc,
InBack,
OutBack,
InOutBack,
InElastic,
OutElastic,
InOutElastic,
InBounce,
OutBounce,
InOutBounce,
}

public static class EaseTypes
{
public const float c1 = 1.70158f;
public const float c2 = c1 * 1.525f;
public const float c3 = c1 + 1;
public const float c4 = (2 * Mathf.PI) / 3;
public const float c5 = (2 * Mathf.PI) / 4.5f;
public const float n1 = 7.5625f;
public const float d1 = 2.75f;

public static float PerformEase(Easing ease, float x)
{
switch (ease)
{
case Easing.InSine:
return 1 - Mathf.Cos((x * Mathf.PI) / 2);
case Easing.OutSine:
return Mathf.Sin((x * Mathf.PI) / 2);
case Easing.InOutSine:
return -(Mathf.Cos(Mathf.PI * x) - 1) / 2;
case Easing.InQuad:
return x * x;
case Easing.OutQuad:
return 1 - (1 - x) * (1 - x);
case Easing.InOutQuad:
return x < 0.5 ? 2 * x * x : 1 - Mathf.Pow(-2 * x + 2, 2) / 2;
case Easing.InCubic:
return x * x * x;
case Easing.OutCubic:
return 1 - Mathf.Pow(1 - x, 3);
case Easing.InOutCubic:
return x < 0.5 ? 4 * x * x * x : 1 - Mathf.Pow(-2 * x + 2, 3) / 2;
case Easing.InQuart:
return x * x * x * x;
case Easing.OutQuart:
return 1 - Mathf.Pow(1 - x, 4);
case Easing.InOutQuart:
return x < 0.5 ? 8 * x * x * x * x : 1 - Mathf.Pow(-2 * x + 2, 4) / 2;
case Easing.InQuint:
return x * x * x * x * x;
case Easing.OutQuint:
return 1 - Mathf.Pow(1 - x, 5);
case Easing.InOutQuint:
return x < 0.5 ? 16 * x * x * x * x * x : 1 - Mathf.Pow(-2 * x + 2, 5) / 2;
case Easing.InExpo:
return x == 0 ? 0 : Mathf.Pow(2, 10 * x - 10);
case Easing.OutExpo:
return x == 1 ? 1 : 1 - Mathf.Pow(2, -10 * x);
case Easing.InOutExpo:
return x == 0
? 0
: x == 1
? 1
: x < 0.5
? Mathf.Pow(2, 20 * x - 10) / 2
: (2 - Mathf.Pow(2, -20 * x + 10)) / 2;
case Easing.InCirc:
return 1 - Mathf.Sqrt(1 - Mathf.Pow(x, 2));
case Easing.OutCirc:
return Mathf.Sqrt(1 - Mathf.Pow(x - 1, 2));
case Easing.InOutCirc:
return x < 0.5
? (1 - Mathf.Sqrt(1 - Mathf.Pow(2 * x, 2))) / 2
: (Mathf.Sqrt(1 - Mathf.Pow(-2 * x + 2, 2)) + 1) / 2;
case Easing.InBack:
return c3 * x * x * x - c1 * x * x;
case Easing.OutBack:
return 1 + c3 * Mathf.Pow(x - 1, 3) + c1 * Mathf.Pow(x - 1, 2);
case Easing.InOutBack:
return x < 0.5
? (Mathf.Pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2
: (Mathf.Pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;
case Easing.InElastic:
return x == 0
? 0
: x == 1
? 1
: -Mathf.Pow(2, 10 * x - 10) * Mathf.Sin((x * 10 - 10.75f) * c4);
case Easing.OutElastic:
return x == 0
? 0
: x == 1
? 1
: Mathf.Pow(2, -10 * x) * Mathf.Sin((x * 10 - 0.75f) * c4) + 1;
case Easing.InOutElastic:
return x == 0
? 0
: x == 1
? 1
: x < 0.5
? -(Mathf.Pow(2, 20 * x - 10) * Mathf.Sin((20 * x - 11.125f) * c5)) / 2
: (Mathf.Pow(2, -20 * x + 10) * Mathf.Sin((20 * x - 11.125f) * c5)) / 2 + 1;
case Easing.InBounce:
return 1 - PerformEase(Easing.OutBounce, 1 - x);
case Easing.OutBounce:
if (x < 1 / d1)
return n1 * x * x;

if (x < 2 / d1)
return n1 * (x -= 1.5f / d1) * x + 0.75f;

if (x < 2.5 / d1)
return n1 * (x -= 2.25f / d1) * x + 0.9375f;

return n1 * (x -= 2.625f / d1) * x + 0.984375f;
case Easing.InOutBounce:
return x < 0.5
? (1 - PerformEase(Easing.OutBounce,(1 - 2 * x))) / 2
: (1 + PerformEase(Easing.OutBounce,(2 * x - 1))) / 2;
default:
Debug.LogWarning($"Ease type {ease} not implemented.");
break;
}
return x;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading