This commit is contained in:
2026-01-11 21:26:52 +08:00
parent 179a971629
commit f2fe6fbf04
21 changed files with 3669 additions and 1396 deletions
+225
View File
@@ -0,0 +1,225 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
namespace AibisDream.UI
{
[ExecuteAlways]
public class ProgressBar : MonoBehaviour
{
[SerializeField]
float currentValue = 0f;
[SerializeField]
float maxValue = 100.0f;
[SerializeField]
bool hasText = true;
[SerializeField]
TextMeshProUGUI text;
[SerializeField]
RectTransform foreground;
[SerializeField]
RectTransform foregroundArea;
[SerializeField]
Vector2Int validRange = new Vector2Int(20, 80);
[SerializeField]
Color normalColor = Color.green;
[SerializeField]
Color abnormalColor = Color.red;
[SerializeField]
RectTransform rangeMarker;
[SerializeField]
Image foregroundImage;
bool bDelayedUpdate = false;
public float CurrentValue
{
get => currentValue;
set
{
if(currentValue == value)
{
return;
}
currentValue = value;
OnValueChanged();
}
}
public float MaxValue
{
get => maxValue;
set
{
if(maxValue == value)
{
return;
}
maxValue = value;
OnValueChanged();
}
}
public bool HasText
{
get => hasText;
set
{
if (hasText == value)
{
return;
}
hasText = value;
UpdateText();
}
}
public Vector2Int ValidRange
{
get => validRange;
set
{
if (validRange == value)
{
return;
}
validRange = value;
ValidateRange();
OnValueChanged();
}
}
void OnValueChanged()
{
if(maxValue < 0)
{
maxValue = 100.0f;
}
if(currentValue < 0)
{
currentValue = 0f;
}
currentValue = Mathf.Clamp(currentValue, 0, maxValue);
UpdateGUI();
}
void Start(){
UpdateGUI();
}
void Update()
{
if(Application.isPlaying)
{
UpdateGUI();
}
else
{
if(bDelayedUpdate)
{
bDelayedUpdate = false;
OnValueChanged();
}
}
}
void UpdateGUI()
{
UpdateForeground();
UpdateRangeMarker();
UpdateText();
}
void UpdateForeground()
{
if (foreground == null || foregroundArea == null)
{
return;
}
float maxWidth = foregroundArea.rect.width;
Vector2 offsetMax = foreground.offsetMax;
offsetMax.x = -(maxWidth - maxWidth*(currentValue / maxValue));
foreground.offsetMax = offsetMax;
// 根据范围检查结果设置颜色
if (foregroundImage != null)
{
foregroundImage.color = IsInRange(currentValue) ? normalColor : abnormalColor;
}
}
void UpdateRangeMarker()
{
if (rangeMarker == null || foregroundArea == null || maxValue <= 0)
{
return;
}
float maxWidth = foregroundArea.rect.width;
float rangeStart = validRange.x / maxValue * maxWidth;
float rangeWidth = (validRange.y - validRange.x) / maxValue * maxWidth;
// 设置范围标记的位置和大小
Vector2 offsetMin = rangeMarker.offsetMin;
Vector2 offsetMax = rangeMarker.offsetMax;
offsetMin.x = rangeStart;
offsetMax.x = -(maxWidth - rangeStart - rangeWidth);
rangeMarker.offsetMin = offsetMin;
rangeMarker.offsetMax = offsetMax;
}
void UpdateText()
{
if (text != null && text.gameObject.activeSelf != hasText)
{
text.gameObject.SetActive(hasText);
}
if (hasText && (text != null))
{
text.text = Mathf.Floor(currentValue) +"/"+ Mathf.Floor(maxValue);
}
}
bool IsInRange(float value)
{
return value >= validRange.x && value <= validRange.y;
}
void ValidateRange()
{
if (validRange.x < 0)
{
validRange.x = 0;
}
if (validRange.y > maxValue)
{
validRange.y = Mathf.RoundToInt(maxValue);
}
if (validRange.x > validRange.y)
{
validRange.x = validRange.y;
}
}
#if UNITY_EDITOR
protected void OnValidate()
{
ValidateRange();
bDelayedUpdate = true;
}
#endif
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 02ff137e6a56f9743b9cbe8b3aeb2195
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: