组装
This commit is contained in:
@@ -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:
|
||||
Reference in New Issue
Block a user