Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/EnergyBarToolkit/RepeatedRendererUGUI.cs
2026-02-21 16:45:37 +08:00

457 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace EnergyBarToolkit
{
[SelectionBase]
[RequireComponent(typeof(EnergyBar))]
[ExecuteInEditMode]
public class RepeatedRendererUGUI : EnergyBarUGUIBase
{
public enum GrowType
{
None = 0,
Grow = 1,
Fade = 2,
Fill = 3
}
public enum BlinkOperator
{
LessThan = 0,
LessOrEqual = 1,
GreaterThan = 2,
GreaterOrEqual = 3
}
public SpriteTex spriteIcon = new SpriteTex();
public SpriteTex spriteSlot = new SpriteTex();
public int repeatCount = 5;
public Vector2 repeatPositionDelta = new Vector2(32f, 0f);
public GrowType growType;
public GrowDirection growDirection;
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;
private bool dirty;
[SerializeField]
private List<Image2> slotImages = new List<Image2>(32);
[SerializeField]
private List<Image2> iconImages = new List<Image2>(32);
[SerializeField]
private List<Vector2> originPositions = new List<Vector2>(32);
[SerializeField]
private Vector2 sizeOrigin;
[SerializeField]
private Vector2 scaleRatio = Vector2.one;
private float _effectBlinkAccum;
public bool forceBlinking { get; set; }
private bool Blink { get; set; }
private Color IconTintTransparent
{
get
{
return new Color(spriteIcon.color.r, spriteIcon.color.g, spriteIcon.color.g, 0f);
}
}
public override void SetNativeSize()
{
if (spriteIcon == null)
{
Rebuild();
if (spriteIcon == null)
{
Debug.LogWarning("Cannot resize bar that has not been created yet");
return;
}
}
Vector2 size = ComputeNativeSize();
SetSize(rectTransform, size);
}
private Vector2 ComputeNativeSize()
{
if (spriteIcon.sprite == null)
{
return Vector2.zero;
}
int num = Mathf.RoundToInt(spriteIcon.sprite.rect.width);
int num2 = Mathf.RoundToInt(spriteIcon.sprite.rect.height);
int num3 = (int)((float)num + Mathf.Abs(repeatPositionDelta.x * (float)(repeatCount - 1)));
int num4 = (int)((float)num2 + Mathf.Abs(repeatPositionDelta.y * (float)(repeatCount - 1)));
return new Vector2(num3, num4);
}
public Image2 GetIconImage(int index)
{
return iconImages[index];
}
public Image2 GetSlotImage(int index)
{
return slotImages[index];
}
public int GetIconCount()
{
return repeatCount;
}
public int GetFullyVisibleIconCount()
{
float f = ValueF2 * (float)repeatCount;
return (int)Mathf.Floor(f);
}
public int GetVisibleIconCount()
{
float f = ValueF2 * (float)repeatCount;
return (int)Mathf.Ceil(f);
}
protected override void Update()
{
base.Update();
UpdateRebuild();
UpdateBar();
UpdateBlinkEffect();
UpdateVisible();
UpdateSize();
}
private void OnValidate()
{
repeatCount = Mathf.Max(1, repeatCount);
}
private void UpdateBar()
{
if (iconImages.Count == 0)
{
return;
}
float num = ValueF2 * (float)repeatCount;
int num2 = (int)Mathf.Floor(num);
float num3 = num - (float)num2;
for (int i = 0; i < repeatCount; i++)
{
Image2 image = iconImages[i];
if (slotImages.Count > 0)
{
Image2 image2 = slotImages[i];
UpdateSlot(image2);
}
if (i < num2)
{
SetIconVisible(image);
continue;
}
if (i > num2)
{
SetIconInvisible(image);
continue;
}
switch (growType)
{
case GrowType.None:
if (Mathf.Approximately(num3, 0f))
{
SetIconInvisible(image);
}
else
{
SetIconVisible(image);
}
break;
case GrowType.Fade:
SetIconVisible(image);
image.color = Color.Lerp(IconTintTransparent, spriteIcon.color, num3);
break;
case GrowType.Grow:
SetIconVisible(image, num3);
break;
case GrowType.Fill:
SetIconVisible(image);
image.growDirection = growDirection;
image.fillValue = num3;
break;
default:
Debug.Log("Unknown grow type: " + growType);
break;
}
}
}
private void UpdateSize()
{
if (!(spriteIcon.sprite == null))
{
Vector2 vector = ComputeNativeSize();
Vector2 size = rectTransform.rect.size;
scaleRatio = new Vector2(size.x / vector.x, size.y / vector.y);
Rect rect = spriteIcon.sprite.rect;
for (int i = 0; i < iconImages.Count; i++)
{
Vector2 originPosition = originPositions[i];
Image2 image = iconImages[i];
UpdateSpriteSize(originPosition, image, rect);
}
for (int j = 0; j < slotImages.Count; j++)
{
Vector2 originPosition2 = originPositions[j];
Image2 image2 = slotImages[j];
UpdateSpriteSize(originPosition2, image2, rect);
}
}
}
private void UpdateSpriteSize(Vector2 originPosition, Image2 image, Rect spriteRect)
{
float x = originPosition.x * scaleRatio.x;
float y = originPosition.y * scaleRatio.y;
MadTransform.SetLocalPosition(image.rectTransform, new Vector3(x, y));
SetSize(image.rectTransform, new Vector2(spriteRect.width * scaleRatio.x, spriteRect.height * scaleRatio.y));
}
private void SetIconVisible(Image2 image, float scale = 1f)
{
image.color = ComputeColor(spriteIcon.color);
image.fillValue = 1f;
MadTransform.SetLocalScale(image.transform, new Vector3(scale, scale, scale));
image.enabled = true;
}
private void UpdateSlot(Image2 image)
{
if (image != null)
{
image.color = ComputeColor(spriteSlot.color);
}
}
private void SetIconInvisible(Image2 image)
{
image.enabled = false;
}
private void UpdateVisible()
{
if (!IsVisible())
{
for (int i = 0; i < iconImages.Count; i++)
{
Image2 image = iconImages[i];
image.enabled = false;
}
for (int j = 0; j < slotImages.Count; j++)
{
Image2 image2 = slotImages[j];
image2.enabled = false;
}
}
else if (Blink)
{
for (int k = 0; k < iconImages.Count; k++)
{
Image2 image3 = iconImages[k];
image3.enabled = false;
}
}
}
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 UpdateRebuild()
{
if (RebuildNeeded())
{
Rebuild();
}
}
private bool RebuildNeeded()
{
if (iconImages.Count == 0 && spriteIcon != null && repeatCount != 0)
{
return true;
}
if (iconImages.Count > 0 && iconImages[0] == null)
{
return true;
}
int currentHash = 37;
currentHash = MadHashCode.Add(currentHash, spriteIcon);
currentHash = MadHashCode.Add(currentHash, spriteSlot);
currentHash = MadHashCode.Add(currentHash, repeatCount);
currentHash = MadHashCode.Add(currentHash, repeatPositionDelta);
currentHash = MadHashCode.Add(currentHash, rectTransform.pivot);
if (currentHash != lastRebuildHash || dirty)
{
lastRebuildHash = currentHash;
dirty = false;
return true;
}
return false;
}
private void Rebuild()
{
RemoveCreatedChildren();
iconImages.Clear();
slotImages.Clear();
originPositions.Clear();
BuildIconsAndSlots();
MoveLabelToTop();
}
private void BuildIconsAndSlots()
{
Vector2 min = Vector2.zero;
Vector2 max = Vector2.zero;
bool hasMinMax = false;
for (int i = 0; i < repeatCount; i++)
{
if (spriteSlot.sprite != null)
{
Image2 image = CreateChild<Image2>(string.Format("slot_{0:D2}", i + 1));
image.sprite = spriteSlot.sprite;
image.color = spriteSlot.color;
image.material = spriteSlot.material;
image.transform.localPosition = repeatPositionDelta * i;
slotImages.Add(image);
Expand(ref min, ref max, ref hasMinMax, image.rectTransform);
}
if (spriteIcon.sprite != null)
{
Image2 image2 = CreateChild<Image2>(string.Format("icon_{0:D2}", i + 1));
image2.sprite = spriteIcon.sprite;
image2.color = spriteIcon.color;
image2.material = spriteIcon.material;
image2.transform.localPosition = repeatPositionDelta * i;
iconImages.Add(image2);
Expand(ref min, ref max, ref hasMinMax, image2.rectTransform);
}
}
sizeOrigin = ComputeNativeSize();
SetNativeSize();
Vector2 vector = new Vector2(0.5f * sizeOrigin.x - rectTransform.pivot.x * sizeOrigin.x, 0.5f * sizeOrigin.y - rectTransform.pivot.y * sizeOrigin.y);
Vector2 vector2 = -repeatPositionDelta * (repeatCount - 1) * 0.5f;
for (int j = 0; j < slotImages.Count; j++)
{
Image2 image3 = slotImages[j];
image3.rectTransform.localPosition = repeatPositionDelta * j + (vector2 + vector);
}
for (int k = 0; k < iconImages.Count; k++)
{
Image2 image4 = iconImages[k];
image4.rectTransform.localPosition = repeatPositionDelta * k + (vector2 + vector);
originPositions.Add(image4.rectTransform.localPosition);
}
if (scaleRatio != Vector2.one)
{
Vector2 size = rectTransform.rect.size;
size.x *= scaleRatio.x;
size.y *= scaleRatio.y;
SetSize(rectTransform, size);
UpdateSize();
}
}
private void Expand(ref Vector2 min, ref Vector2 max, ref bool hasMinMax, RectTransform tr)
{
Rect rect = tr.rect;
float num = rect.xMin + tr.localPosition.x;
float num2 = rect.xMax + tr.localPosition.x;
float num3 = rect.yMin + tr.localPosition.y;
float num4 = rect.yMax + tr.localPosition.y;
if (!hasMinMax)
{
min.x = num;
min.y = num3;
max.x = num2;
max.y = num4;
hasMinMax = true;
return;
}
if (num < min.x)
{
min.x = num;
}
if (num3 < min.y)
{
min.y = num3;
}
if (num2 > max.x)
{
max.x = num2;
}
if (num4 > max.y)
{
max.y = num4;
}
}
}
}