Files
2026-02-21 16:45:37 +08:00

294 lines
4.8 KiB
C#

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
namespace UIWidgets
{
[AddComponentMenu("UI/Progressbar", 260)]
public class Progressbar : MonoBehaviour
{
public bool startOnAwake = true;
[SerializeField]
public int Max = 100;
[SerializeField]
private int _value;
[SerializeField]
private ProgressbarDirection Direction;
[SerializeField]
private ProgressbarTypes type;
[SerializeField]
public RawImage IndeterminateBar;
[SerializeField]
public GameObject DeterminateBar;
[SerializeField]
public Image EmptyBar;
[SerializeField]
public Text EmptyBarText;
[SerializeField]
private Image fullBar;
[SerializeField]
public Text FullBarText;
[SerializeField]
public RectTransform BarMask;
[SerializeField]
private ProgressbarTextTypes textType;
[SerializeField]
public float Speed = 0.1f;
private Func<Progressbar, string> textFunc = TextPercent;
private IEnumerator currentAnimation;
public int Value
{
get
{
return _value;
}
set
{
if (value > Max)
{
value = Max;
}
_value = value;
UpdateProgressbar();
}
}
public ProgressbarTypes Type
{
get
{
return type;
}
set
{
type = value;
ToggleType();
}
}
public Image FullBar
{
get
{
return fullBar;
}
set
{
fullBar = value;
}
}
private RectTransform FullBarRectTransform
{
get
{
return fullBar.transform as RectTransform;
}
}
[SerializeField]
public ProgressbarTextTypes TextType
{
get
{
return textType;
}
set
{
textType = value;
ToggleTextType();
}
}
public Func<Progressbar, string> TextFunc
{
get
{
return textFunc;
}
set
{
textFunc = value;
UpdateText();
}
}
public bool IsAnimationRun { get; protected set; }
private void Awake()
{
if (startOnAwake)
{
Animate();
}
}
public static string TextNone(Progressbar bar)
{
return string.Empty;
}
public static string TextPercent(Progressbar bar)
{
return string.Format("{0:P0}", (float)bar.Value / (float)bar.Max);
}
public static string TextRange(Progressbar bar)
{
return string.Format("{0} / {1}", bar.Value, bar.Max);
}
public void Animate(int? targetValue = null)
{
if (currentAnimation != null)
{
StopCoroutine(currentAnimation);
}
if (Type == ProgressbarTypes.Indeterminate)
{
currentAnimation = IndeterminateAnimation();
}
else
{
currentAnimation = DeterminateAnimation((!targetValue.HasValue) ? Max : targetValue.Value);
}
IsAnimationRun = true;
StartCoroutine(currentAnimation);
}
public void Stop()
{
if (IsAnimationRun)
{
StopCoroutine(currentAnimation);
IsAnimationRun = false;
}
}
private IEnumerator DeterminateAnimation(int targetValue)
{
if (targetValue > Max)
{
targetValue = Max;
}
int delta = targetValue - Value;
if (delta != 0)
{
while (true)
{
if (delta > 0)
{
_value++;
}
else
{
_value--;
}
UpdateProgressbar();
if (_value == targetValue)
{
break;
}
yield return new WaitForSeconds(Speed);
}
}
IsAnimationRun = false;
}
private IEnumerator IndeterminateAnimation()
{
while (true)
{
Rect r = IndeterminateBar.uvRect;
if (Direction == ProgressbarDirection.Horizontal)
{
r.x = Time.time * Speed % 1f;
}
else
{
r.y = Time.time * Speed % 1f;
}
IndeterminateBar.uvRect = r;
yield return null;
}
}
public void Refresh()
{
FullBar = fullBar;
ToggleType();
ToggleTextType();
UpdateProgressbar();
}
private void UpdateProgressbar()
{
if (BarMask != null && FullBar != null)
{
float num = (float)Value / (float)Max;
BarMask.sizeDelta = ((Direction != ProgressbarDirection.Horizontal) ? new Vector2(BarMask.sizeDelta.x, FullBarRectTransform.rect.height * num) : new Vector2(FullBarRectTransform.rect.width * num, BarMask.sizeDelta.y));
}
UpdateText();
}
private void UpdateText()
{
string text = textFunc(this);
if (FullBarText != null)
{
FullBarText.text = text;
}
if (EmptyBarText != null)
{
EmptyBarText.text = text;
}
}
private void ToggleType()
{
bool flag = type == ProgressbarTypes.Determinate;
if (DeterminateBar != null)
{
DeterminateBar.gameObject.SetActive(flag);
}
if (IndeterminateBar != null)
{
IndeterminateBar.gameObject.SetActive(!flag);
}
}
private void ToggleTextType()
{
if (TextType == ProgressbarTextTypes.None)
{
textFunc = TextNone;
}
else if (TextType == ProgressbarTextTypes.Percent)
{
textFunc = TextPercent;
}
else if (TextType == ProgressbarTextTypes.Range)
{
textFunc = TextRange;
}
}
}
}