123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // Licensed under the MIT License. See LICENSE in the project root for license information.
- using UnityEngine;
- namespace Microsoft.MixedReality.Toolkit.UI
- {
- /// <summary>
- /// Controls how the standard indeterminate loader moves and behaves over time.
- /// </summary>
- /// <remarks>
- /// This loader is calculated dynamically based on Sine and Cosine
- /// </remarks>
- [AddComponentMenu("Scripts/MRTK/SDK/LoaderController")]
- public class LoaderController : MonoBehaviour
- {
- /// <summary>
- /// Total strength of movement of the loading animation
- /// </summary>
- [SerializeField]
- [Tooltip("Total strength of movement of the loading animation")]
- private float amplitude = 0.05f;
- public float Amplitude
- {
- get => amplitude;
- set => amplitude = value;
- }
- /// <summary>
- /// How often <see cref="amplitude"/> happens
- /// </summary>
- [SerializeField]
- [Tooltip("How often 'amplitude' happens")]
- private float frequency = 3.0f;
- public float Frequency
- {
- get => frequency;
- set => frequency = value;
- }
- /// <summary>
- /// The base local position for the dots' parent
- /// </summary>
- [SerializeField]
- [Tooltip("The base local position for the dots' parent")]
- private float dotOffset = 0.05f;
- public float DotOffset
- {
- get => dotOffset;
- set => dotOffset = value;
- }
- /// <summary>
- /// The base scale unit for the dots' parent
- /// </summary>
- [SerializeField]
- [Tooltip("The base scale unit for the dots' parent")]
- private float dotSetScale = 0.06f;
- public float DotSetScale
- {
- get => dotSetScale;
- set => dotSetScale = value;
- }
- /// <summary>
- /// Use low frequency oscillation with the Sine calculation.
- /// </summary>
- [SerializeField]
- [Tooltip("Use low frequency oscillation with the Sine calculation.")]
- private bool lFOsin = false;
- public bool LFOsin
- {
- get => lFOsin;
- set => lFOsin = value;
- }
- /// <summary>
- /// Use low frequency oscillation with the Cosine calculation.
- /// </summary>
- [SerializeField]
- [Tooltip("Use low frequency oscillation with the Cosine calculation.")]
- private bool lFOcos = false;
- public bool LFOcos
- {
- get => lFOcos;
- set => lFOcos = value;
- }
- /// <summary>
- /// Low Frequency oscillation frequency
- /// </summary>
- [SerializeField]
- [Tooltip("Low frequency oscillation frequency")]
- private float lFOfreq = 1.0f;
- public float LFOfreq
- {
- get => lFOfreq;
- set => lFOfreq = value;
- }
- /// <summary>
- /// Low Frequency oscillation amplitude
- /// </summary>
- [SerializeField]
- [Tooltip("Low Frequency oscillation amplitude")]
- private float lFOamp = 0.1f;
- public float LFOamp
- {
- get => lFOamp;
- set => lFOamp = value;
- }
- /// <summary>
- /// Reverses dots' orbit rotation path
- /// </summary>
- [SerializeField]
- [Tooltip("Reverses dots' orbit rotation path")]
- private bool reverseOrbit = false;
- public bool ReverseOrbit
- {
- get => reverseOrbit;
- set => reverseOrbit = value;
- }
- /// <summary>
- /// Inverts dots' position in orbit
- /// </summary>
- [SerializeField]
- [Tooltip("Inverts dots' position in orbit")]
- private bool invertOrbitOffset = false;
- public bool InvertOrbitOffset
- {
- get => invertOrbitOffset;
- set => invertOrbitOffset = value;
- }
- /// <summary>
- /// Multiplier to dot's rotation calculation
- /// </summary>
- [SerializeField]
- [Tooltip("Multiplier to dot's rotation calculation")]
- private float dotSpinMultiplier = 0.3f;
- public float DotSpinMultiplier
- {
- get => dotSpinMultiplier;
- set => dotSpinMultiplier = value;
- }
- /// <summary>
- /// Multiplier to dot's scale calculation
- /// </summary>
- [SerializeField]
- [Tooltip("Multiplier to dot's scale calculation")]
- private float dotScaleMultipler = 0.0f;
- public float DotScaleMultipler
- {
- get => dotScaleMultipler;
- set => dotScaleMultipler = value;
- }
- /// <summary>
- /// When enabled, the dot scale uses Cosine to determine scale with including <see cref="dotSetScale"/>.
- /// Otherwise, it will use Sine.
- /// </summary>
- [SerializeField]
- [Tooltip("When enabled, the dot scale uses Cosine to determine scale with including 'dotSetScale'. Otherwise, it will use Sine.")]
- private bool sinCosSplitScale = false;
- public bool SinCosSplitScale
- {
- get => sinCosSplitScale;
- set => sinCosSplitScale = value;
- }
- /// <summary>
- /// Calculates the time cycle for the trigonometric functions
- /// </summary>
- private float Cycles
- {
- get
- {
- if (reverseOrbit)
- {
- return (frequency < 0.0f) ? (Time.time / 0.000001f) * -1.0f : (Time.time / frequency) * -1.0f;
- }
- else
- {
- return (frequency < 0.0f) ? Time.time / 0.000001f : Time.time / frequency;
- }
- }
- }
- private float degPerSec;
- private Vector3 parentNewPos = Vector3.zero;
- private Transform dot01;
- private Vector3 dot01NewPos = Vector3.zero;
- private Vector3 dot01NewScale = Vector3.zero;
- private Vector3 dot01NewRot = Vector3.zero;
- private Transform dot02;
- private Vector3 dot02NewPos = Vector3.zero;
- private Vector3 dot02NewScale = Vector3.zero;
- private Vector3 dot02NewRot = Vector3.zero;
- private const float tau = Mathf.PI * 2.0f;
- private void OnEnable()
- {
- if (dot01 == null)
- {
- dot01 = gameObject.transform.GetChild(0);
- }
- if (dot02 == null)
- {
- dot02 = gameObject.transform.GetChild(1);
- }
- }
- private void Update()
- {
- degPerSec = Time.deltaTime * 360f;
- AnimateParent();
- AnimateDotTransforms();
- }
- private void AnimateParent()
- {
- float cosX = Mathf.Cos(Cycles * tau) * amplitude;
- float sinY = Mathf.Sin(Cycles * tau) * amplitude;
- if (invertOrbitOffset == true)
- {
- cosX = -cosX;
- sinY = -sinY;
- }
- parentNewPos.Set(cosX, sinY, 0f);
- transform.localPosition = parentNewPos;
- if (lFOsin == true)
- {
- dotSpinMultiplier = Mathf.Sin(Time.time * lFOfreq) * lFOamp;
- }
- else if (lFOcos == true)
- {
- dotSpinMultiplier = Mathf.Cos(Time.time * lFOfreq) * lFOamp;
- }
- transform.Rotate(Vector3.forward * (degPerSec * dotSpinMultiplier));
- }
- private void AnimateDotTransforms()
- {
- // SaveLocal dot groups' scale
- float sinScaleCalc = dotSetScale + Mathf.Sin(Cycles * tau / 2) * dotScaleMultipler;
- float cosScaleCalc = dotSetScale + Mathf.Cos(Cycles * tau / 2) * dotScaleMultipler;
- if (sinCosSplitScale == true)
- {
- dot01NewPos.Set(cosScaleCalc, cosScaleCalc, cosScaleCalc);
- }
- else
- {
- dot01NewPos.Set(sinScaleCalc, sinScaleCalc, sinScaleCalc);
- }
- dot01.localScale = dot01NewPos;
- dot02NewPos.Set(sinScaleCalc, sinScaleCalc, sinScaleCalc);
- dot02.localScale = dot02NewPos;
- // SaveLocal dot groups' position Offset from Parent-Null Center
- dot01NewPos.Set(dotOffset, dotOffset, 0f);
- dot02NewPos.Set(-dotOffset, -dotOffset, 0f);
- dot01.transform.localPosition = dot01NewPos;
- dot02.transform.localPosition = dot02NewPos;
- }
- }
- }
|