Animate runtime progress bars with UI Toolkit
As I mentioned above, this progress bar will have three distinct animations all tied to the progress of the Drum clip:
Additionally, the progress bar will only become visible while animating and will hide from the screen once complete.
Add the following global methods and update Start
to set the references and disable the m_Root’s visibility on load:
private Label m_PercentageText;
private VisualElement m_OuterPivot;
private VisualElement m_InnerPivot;
private void Start()
{
//Grab a reference to the root element that is drawn
m_Root = GetComponent<UIDocument>().rootVisualElement;
//Grab progress bar references
m_PercentageText = m_Root.Q<Label>("txt_Percentage");
m_OuterPivot = m_Root.Q<VisualElement>("Outer_Pivot");
m_InnerPivot = m_Root.Q<VisualElement>("Inner_Pivot");
//Display the view of the panel
m_Root.style.visibility = Visibility.Hidden;
}
Next, add a new Coroutine which will animate the UI:
private IEnumerator AnimateUI(float duration)
{
//Reset the text
m_PercentageText.text = "1%";
//Toggle visibility on
m_Root.style.visibility = Visibility.Visible;
//Set the tweens
Tween outerTween = DOTween.To(() => m_OuterPivot.worldTransform.rotation.eulerAngles, x => m_OuterPivot.transform.rotation = Quaternion.Euler(x), new Vector3(0, 0, 360), 5 / 0.5f).SetEase(Ease.Linear).SetLoops(-1);
Tween innerTween = DOTween.To(() => m_InnerPivot.worldTransform.rotation.eulerAngles, x => m_InnerPivot.transform.rotation = Quaternion.Euler(x), new Vector3(0, 0, -360), duration / 0.5f).SetEase(Ease.Linear).SetLoops(-1);
DOTween.To(() => 5, x => m_PercentageText.text = $"{x}%", 100, duration).SetEase(Ease.Linear).OnComplete(() => { outerTween.Kill(); innerTween.Kill(); });
//Wait until tweens finish (+1 extra second for display purposes)
yield return new WaitForSeconds(duration + 1f);
//Disable the visiblity
m_Root.style.visibility = Visibility.Hidden;
}
The AnimateUI
Coroutine does three major things:
SetLoops
is telling the Tween how many times to loop with -1 meaning “infinite”. The last new concept introduced is the OnComplete()
method, which in this case is telling the outerTween and innerTweens to stop. If you were to take the OnComplete out, you would see the text hit 100% but the inner and outer images would continue to rotate.The last thing you need to do is start the coroutine. Add StartCoroutine(AnimateUI(duration));
to to AnimateCircularProgressBar
. Push play and you should see the progress bar appear when he starts to drum.