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

428 lines
11 KiB
C#

using System;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
namespace EnergyBarToolkit
{
[SelectionBase]
[ExecuteInEditMode]
[RequireComponent(typeof(EnergyBar))]
public class SlicedRendererUGUI : EnergyBarUGUIBase
{
public enum BlinkOperator
{
LessThan = 0,
LessOrEqual = 1,
GreaterThan = 2,
GreaterOrEqual = 3
}
public Sprite spriteBar;
public ColorType spriteBarColorType;
public Color spriteBarColor = Color.white;
public Gradient spriteBarGradient;
public float spriteBarMinSize;
public GrowDirection growDirection;
public Vector3 barImageScale = new Vector3(1f, 1f, 1f);
public Vector3 barImageOffset = new Vector3(0f, 0f, 0f);
public bool effectBlink;
public float effectBlinkValue = 0.2f;
public float effectBlinkRatePerSecond = 1f;
public Color effectBlinkColor = new Color(1f, 1f, 1f, 0f);
public BlinkOperator effectBlinkOperator = BlinkOperator.LessOrEqual;
[SerializeField]
private int lastRebuildHash;
[SerializeField]
private bool dirty;
[FormerlySerializedAs("barImage")]
[SerializeField]
private Image imageBar;
[FormerlySerializedAs("burnImage")]
[SerializeField]
private Image imageBurn;
private float _effectBlinkAccum;
public bool forceBlinking { get; set; }
private bool Blink { get; set; }
public override void SetNativeSize()
{
if (imageBar == null)
{
Rebuild();
if (imageBar == null)
{
Debug.LogWarning("Cannot resize bar that has not been created yet");
return;
}
}
int num = Mathf.RoundToInt(imageBar.sprite.rect.width);
int num2 = Mathf.RoundToInt(imageBar.sprite.rect.height);
rectTransform.anchorMax = rectTransform.anchorMin;
rectTransform.sizeDelta = new Vector2(num, num2);
}
public bool GrowDirectionSupportedByFollowEffect(GrowDirection growDirection)
{
switch (growDirection)
{
case GrowDirection.LeftToRight:
case GrowDirection.RightToLeft:
case GrowDirection.BottomToTop:
case GrowDirection.TopToBottom:
return true;
default:
return false;
}
}
protected override void Start()
{
base.Start();
if (imageBar == null)
{
dirty = true;
}
}
protected override void Update()
{
base.Update();
UpdateRebuild();
UpdateNonIntrusive();
}
private void UpdateSize()
{
RectTransform component = GetComponent<RectTransform>();
for (int i = 0; i < createdChildren.Count; i++)
{
GameObject gameObject = createdChildren[i];
RectTransform component2 = gameObject.GetComponent<RectTransform>();
SetSize(component2, component.rect.size);
}
}
private void UpdateNonIntrusive()
{
UpdateSize();
UpdateBarScaleAndOffset();
UpdateValue();
UpdateBlinkEffect();
UpdateBurnEffect();
UpdateBarOffset();
UpdateColor();
}
private void UpdateBarScaleAndOffset()
{
if (imageBar != null)
{
Vector2 pivot = rectTransform.pivot;
Rect rect = imageBar.rectTransform.rect;
float num = (0f - (pivot.x - 0.5f)) * rect.width;
float num2 = (0f - (pivot.y - 0.5f)) * rect.height;
Vector3 localPosition = new Vector3(barImageOffset.x + num, barImageOffset.y + num2, barImageOffset.z);
MadTransform.SetLocalScale(imageBar.transform, barImageScale);
MadTransform.SetLocalPosition(imageBar.transform, localPosition);
if (imageBurn != null)
{
MadTransform.SetLocalScale(imageBurn.transform, barImageScale);
MadTransform.SetLocalPosition(imageBurn.transform, localPosition);
}
}
}
private void UpdateBarOffset()
{
if (imageBar != null)
{
UpdateBarOffset(imageBar);
if (imageBurn != null)
{
UpdateBarOffset(imageBurn);
}
}
}
private void UpdateBarOffset(Image bar)
{
Vector2 pivot = rectTransform.pivot;
Rect rect = bar.rectTransform.rect;
float num = (0f - (pivot.x - 0.5f)) * rect.width;
float num2 = (0f - (pivot.y - 0.5f)) * rect.height;
Vector3 localPosition = new Vector3(bar.transform.localPosition.x + barImageOffset.x + num, bar.transform.localPosition.y + barImageOffset.y + num2, barImageOffset.z);
MadTransform.SetLocalPosition(bar.transform, localPosition);
}
private void UpdateValue()
{
if (!(imageBar == null))
{
SetBarValue(imageBar, ValueF2);
}
}
private void SetBarValue(Image image, float valueF)
{
RectTransform rectTransform = image.rectTransform;
float x = rectTransform.localPosition.x;
float y = rectTransform.localPosition.y;
float width = rectTransform.rect.width;
float height = rectTransform.rect.height;
float num = spriteBarMinSize;
float width2 = base.rectTransform.rect.width;
float height2 = base.rectTransform.rect.height;
float w = (width2 - num) * valueF + num;
float h = (height2 - num) * valueF + num;
switch (growDirection)
{
case GrowDirection.LeftToRight:
SetSize(rectTransform, w, rectTransform.rect.height);
break;
case GrowDirection.RightToLeft:
SetSize(rectTransform, w, rectTransform.rect.height);
break;
case GrowDirection.BottomToTop:
SetSize(rectTransform, rectTransform.rect.width, h);
break;
case GrowDirection.TopToBottom:
SetSize(rectTransform, rectTransform.rect.width, h);
break;
case GrowDirection.RadialCW:
Debug.LogError("Unsupported grow direction: " + growDirection, this);
break;
case GrowDirection.RadialCCW:
Debug.LogError("Unsupported grow direction: " + growDirection, this);
break;
case GrowDirection.ExpandHorizontal:
SetSize(rectTransform, w, rectTransform.rect.height);
break;
case GrowDirection.ExpandVertical:
SetSize(rectTransform, rectTransform.rect.width, h);
break;
default:
throw new ArgumentOutOfRangeException();
case GrowDirection.ColorChange:
break;
}
float width3 = rectTransform.rect.width;
float height3 = rectTransform.rect.height;
float num2 = width3 - width;
float num3 = height3 - height;
switch (growDirection)
{
case GrowDirection.LeftToRight:
rectTransform.localPosition = new Vector3(x + num2 / 2f, rectTransform.localPosition.y, rectTransform.localPosition.z);
break;
case GrowDirection.RightToLeft:
rectTransform.localPosition = new Vector3(x - num2 / 2f, rectTransform.localPosition.y, rectTransform.localPosition.z);
break;
case GrowDirection.BottomToTop:
rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, y + num3 / 2f, rectTransform.localPosition.z);
break;
case GrowDirection.TopToBottom:
rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, y - num3 / 2f, rectTransform.localPosition.z);
break;
case GrowDirection.RadialCW:
Debug.LogError("Unsupported grow direction: " + growDirection, this);
break;
case GrowDirection.RadialCCW:
Debug.LogError("Unsupported grow direction: " + growDirection, this);
break;
case GrowDirection.ExpandHorizontal:
rectTransform.localPosition = new Vector3(0f, 0f, rectTransform.localPosition.z);
break;
case GrowDirection.ExpandVertical:
rectTransform.localPosition = new Vector3(0f, 0f, rectTransform.localPosition.z);
break;
default:
throw new ArgumentOutOfRangeException();
case GrowDirection.ColorChange:
break;
}
image.SetVerticesDirty();
}
private void UpdateBlinkEffect()
{
if (forceBlinking)
{
Blink = EnergyBarCommons.Blink(effectBlinkRatePerSecond, ref _effectBlinkAccum);
}
else if (CanBlink())
{
Blink = EnergyBarCommons.Blink(effectBlinkRatePerSecond, ref _effectBlinkAccum);
}
else
{
Blink = false;
}
}
private bool CanBlink()
{
if (!effectBlink)
{
return false;
}
switch (effectBlinkOperator)
{
case BlinkOperator.LessThan:
return ValueF2 < effectBlinkValue;
case BlinkOperator.LessOrEqual:
return ValueF2 <= effectBlinkValue;
case BlinkOperator.GreaterThan:
return ValueF2 > effectBlinkValue;
case BlinkOperator.GreaterOrEqual:
return ValueF2 >= effectBlinkValue;
default:
throw new ArgumentOutOfRangeException();
}
}
private void UpdateBurnEffect()
{
if (!(imageBurn == null))
{
if (Mathf.Approximately(ValueFBurn, ValueF2))
{
imageBurn.enabled = false;
return;
}
imageBurn.enabled = true;
imageBurn.color = GetBurnColor();
SetBarValue(imageBurn, ValueFBurn);
}
}
private Color GetBurnColor()
{
Color localColor = effectBurnSprite.color;
if (Blink)
{
localColor = new Color(0f, 0f, 0f, 0f);
}
return ComputeColor(localColor);
}
private void UpdateColor()
{
Color color = ComputeBarColor();
imageBar.color = color;
}
private Color ComputeBarColor()
{
Color localColor = Color.white;
if (growDirection == GrowDirection.ColorChange)
{
localColor = spriteBarGradient.Evaluate(base.energyBar.ValueF);
}
else
{
switch (spriteBarColorType)
{
case ColorType.Solid:
localColor = spriteBarColor;
break;
case ColorType.Gradient:
localColor = spriteBarGradient.Evaluate(base.energyBar.ValueF);
break;
default:
MadDebug.Assert(false, "Unkwnown option: " + spriteBarColorType);
break;
}
}
if (Blink)
{
localColor = effectBlinkColor;
}
return ComputeColor(localColor);
}
public void UpdateRebuild()
{
if (RebuildNeeded())
{
Rebuild();
}
}
private bool RebuildNeeded()
{
int currentHash = 37;
currentHash = MadHashCode.Add(currentHash, (spriteBar != null) ? spriteBar.GetInstanceID() : 0);
currentHash = MadHashCode.AddList(currentHash, spritesBackground);
currentHash = MadHashCode.AddList(currentHash, spritesForeground);
currentHash = MadHashCode.Add(currentHash, (int)spriteBarColorType);
currentHash = MadHashCode.Add(currentHash, (int)growDirection);
currentHash = MadHashCode.Add(currentHash, label);
currentHash = MadHashCode.Add(currentHash, effectBurn);
currentHash = MadHashCode.Add(currentHash, effectBurnSprite);
currentHash = MadHashCode.Add(currentHash, rectTransform.pivot);
if (currentHash != lastRebuildHash || dirty)
{
lastRebuildHash = currentHash;
dirty = false;
return true;
}
return false;
}
private void Rebuild()
{
RemoveCreatedChildren();
BuildBackgroundImages();
if (effectBurn)
{
BuildBurnBar();
}
BuildBar();
BuildForegroundImages();
UpdateSize();
MoveLabelToTop();
}
private void BuildBurnBar()
{
imageBurn = CreateChild<Image>("burn_bar");
imageBurn.type = Image.Type.Sliced;
imageBurn.sprite = imageBurn.sprite ?? spriteBar;
imageBurn.SetNativeSize();
}
private void BuildBar()
{
imageBar = CreateChild<Image>("bar");
imageBar.type = Image.Type.Sliced;
imageBar.sprite = spriteBar;
imageBar.SetNativeSize();
}
protected override Image.Type GetImageType()
{
return Image.Type.Sliced;
}
}
}