using System.Threading.Tasks; using UnityEngine; using UnityEngine.UI; namespace SC.XR.Unity { public class ProgressIndicatorBar : MonoBehaviour, IProgressIndicator { const float SmoothProgressSpeed = 0.5f; [SerializeField] [Range(0f, 1f)] private float progress = 0f; public ProgressIndicatorState State { get { return state; } } public float Progress { get { return progress; } set { if (value >= 0 && value <= 1) { progress = value; } } } // The animated progress bar object [SerializeField] private Transform progressBar = null; // The progress text used by all non-'None' progress styles [SerializeField] private Text progressText = null; // Whether to display the percentage as text in addition to the loading bar [SerializeField] private bool displayPercentage = true; private float smoothProgress = 0f; private float lastSmoothProgress = -1; private ProgressIndicatorState state = ProgressIndicatorState.Closed; private Vector3 barScale = Vector3.one; public async Task OpenAsync() { if (state != ProgressIndicatorState.Closed) { throw new System.Exception("Can't open in state " + state); } smoothProgress = 0; lastSmoothProgress = 0; gameObject.SetActive(true); state = ProgressIndicatorState.Opening; await Task.Yield(); state = ProgressIndicatorState.Open; } public async Task CloseAsync() { if (state != ProgressIndicatorState.Open) { throw new System.Exception("Can't close in state " + state); } state = ProgressIndicatorState.Closing; await Task.Yield(); state = ProgressIndicatorState.Closed; gameObject.SetActive(false); } public async Task AwaitTransitionAsync() { while (isActiveAndEnabled) { switch (state) { case ProgressIndicatorState.Open: case ProgressIndicatorState.Closed: return; default: break; } await Task.Yield(); } } public void SetProgress(float p) { progress = p; } private void Update() { if (state != ProgressIndicatorState.Open) { return; } smoothProgress = Mathf.Lerp(smoothProgress, progress, SmoothProgressSpeed); if (smoothProgress > 0.99f) { smoothProgress = 1f; } barScale.x = Mathf.Clamp(smoothProgress, 0.01f, 1f); progressBar.localScale = barScale; progressText.gameObject.SetActive(displayPercentage); if (lastSmoothProgress != smoothProgress) { progressText.text = string.Format("{0:P0}", smoothProgress); lastSmoothProgress = smoothProgress; } } } }