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

394 lines
9.0 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace EnergyBarToolkit
{
[RequireComponent(typeof(EnergyBar))]
[ExecuteInEditMode]
public class RepeatedRenderer3D : EnergyBar3DBase
{
public enum GrowType
{
None = 0,
Grow = 1,
Fade = 2,
Fill = 3
}
public enum CutDirection
{
LeftToRight = 0,
TopToBottom = 1,
RightToLeft = 2,
BottomToTop = 3
}
public Texture2D textureIcon;
public Texture2D textureSlot;
public string atlasTextureIconGUID;
public string atlasTextureSlotGUID;
public Color tintIcon = Color.white;
public Color tintSlot = Color.white;
public int repeatCount = 5;
public Vector2 repeatPositionDelta = new Vector2(32f, 0f);
public float repeatRotationDelta;
public GrowType growType;
public MadSprite.FillType fillDirection;
private List<MadSprite> slotSprites = new List<MadSprite>();
private List<MadSprite> iconSprites = new List<MadSprite>();
private int lastRebuildHash;
private bool dirty = true;
public override Pivot pivot
{
get
{
return base.pivot;
}
set
{
bool flag = base.pivot != value;
base.pivot = value;
if (flag)
{
Rebuild();
}
}
}
public override Rect DrawAreaRect
{
get
{
Rect rect;
Vector2 iconSize;
if (iconSprites != null && iconSprites.Count > 0 && iconSprites[0] != null)
{
rect = iconSprites[0].GetBounds();
iconSize = new Vector2(rect.width, rect.height);
}
else if (!base.useAtlas && textureIcon != null)
{
iconSize = new Vector2(textureIcon.width, textureIcon.height);
rect = new Rect((0f - iconSize.x) / 2f, iconSize.y / 2f, iconSize.x, iconSize.y);
}
else
{
if (!base.useAtlas || !AtlasTextureValid(atlasTextureIconGUID))
{
return default(Rect);
}
MadAtlas.Item item = atlas.GetItem(atlasTextureIconGUID);
iconSize = new Vector2(item.pixelsWidth, item.pixelsHeight);
rect = new Rect((0f - iconSize.x) / 2f, iconSize.y / 2f, iconSize.x, iconSize.y);
}
Vector2 vector = ComputeDrawAreaSize(iconSize);
Vector2 vector2 = LocalIconOffset(iconSize);
return new Rect(rect.x + vector2.x, rect.y + vector2.y, vector.x, vector.y);
}
}
private Color IconTintTransparent
{
get
{
return new Color(tintIcon.r, tintIcon.g, tintIcon.g, 0f);
}
}
public event Action<MadSprite> onIconShow;
public event Action<MadSprite> onIconHide;
public MadSprite GetSlotSprite(int index)
{
return slotSprites[index];
}
public MadSprite GetIconSprite(int index)
{
return iconSprites[index];
}
private new void Start()
{
base.Start();
}
protected override void Update()
{
base.Update();
if (RebuildNeeded())
{
Rebuild();
}
if (!(panel == null))
{
UpdateBar();
UpdateVisible();
}
}
private void UpdateBar()
{
if (iconSprites == null || iconSprites.Count != repeatCount)
{
return;
}
float num = ValueF2 * (float)repeatCount;
int num2 = (int)Mathf.Floor(num);
float num3 = num - (float)num2;
for (int i = 0; i < repeatCount; i++)
{
MadSprite madSprite = iconSprites[i];
if (slotSprites.Count > 0)
{
MadSprite sprite = slotSprites[i];
UpdateSlot(sprite);
}
if (i < num2)
{
SetIconVisible(madSprite);
continue;
}
if (i > num2)
{
SetIconInvisible(madSprite);
continue;
}
if (num3 == 0f)
{
SetIconInvisible(madSprite);
}
else
{
SetIconVisible(madSprite);
}
switch (growType)
{
case GrowType.Fade:
madSprite.tint = Color.Lerp(IconTintTransparent, tintIcon, num3);
break;
case GrowType.Grow:
madSprite.transform.localScale = new Vector3(num3, num3, num3);
break;
case GrowType.Fill:
madSprite.fillType = fillDirection;
madSprite.fillValue = num3;
break;
default:
Debug.Log("Unknown grow type: " + growType);
break;
case GrowType.None:
break;
}
}
}
private void SetIconVisible(MadSprite sprite)
{
bool flag = !sprite.visible;
sprite.tint = ComputeColor(tintIcon);
sprite.fillValue = 1f;
MadTransform.SetLocalScale(sprite.transform, 1f);
sprite.visible = true;
if (flag && this.onIconShow != null)
{
this.onIconShow(sprite);
}
}
private void UpdateSlot(MadSprite sprite)
{
if (sprite != null)
{
sprite.tint = ComputeColor(tintSlot);
MadTransform.SetLocalScale(sprite.transform, 1f);
}
}
private void SetIconInvisible(MadSprite sprite)
{
bool visible = sprite.visible;
sprite.visible = false;
if (visible && this.onIconHide != null)
{
this.onIconHide(sprite);
}
}
private void UpdateVisible()
{
bool flag = IsVisible();
if (flag)
{
return;
}
foreach (MadSprite iconSprite in iconSprites)
{
iconSprite.visible = flag;
}
foreach (MadSprite slotSprite in slotSprites)
{
slotSprite.visible = flag;
}
}
private bool RebuildNeeded()
{
if (panel == null)
{
return false;
}
MadHashCode madHashCode = new MadHashCode();
madHashCode.AddEnumerable(texturesBackground);
madHashCode.Add(atlas);
madHashCode.Add(textureIcon);
madHashCode.Add(textureSlot);
madHashCode.Add(atlasTextureIconGUID);
madHashCode.Add(atlasTextureSlotGUID);
madHashCode.Add(repeatCount);
madHashCode.Add(repeatPositionDelta);
madHashCode.Add(repeatRotationDelta);
madHashCode.Add(guiDepth);
madHashCode.Add(growType);
madHashCode.Add(fillDirection);
madHashCode.Add(labelEnabled);
madHashCode.Add(labelFont);
madHashCode.Add(pivot);
madHashCode.Add(premultipliedAlpha);
int hashCode = madHashCode.GetHashCode();
if (hashCode != lastRebuildHash || dirty)
{
lastRebuildHash = hashCode;
dirty = false;
return true;
}
return false;
}
protected override void Rebuild()
{
base.Rebuild();
RebuildClear();
int depth = RebuildBuild();
RebuildLabel(depth);
UpdateBar();
UpdateContainer();
}
private void RebuildClear()
{
iconSprites.Clear();
slotSprites.Clear();
}
private int RebuildBuild()
{
int depth = guiDepth * 32;
return BuildTextures(depth);
}
private int BuildTextures(int depth)
{
Vector2 zero = Vector2.zero;
float num = 0f;
for (int i = 0; i < repeatCount; i++)
{
if (TextureValid(textureSlot, atlasTextureSlotGUID))
{
string text = string.Format("slot_{0:D2}", i + 1);
MadSprite madSprite = CreateHidden<MadSprite>(text);
SetTexture(madSprite, textureSlot, atlasTextureSlotGUID);
madSprite.transform.localPosition = zero;
madSprite.transform.localEulerAngles = new Vector3(0f, 0f, num);
Vector2 v = LocalIconOffset(madSprite.size);
v = RotateVector(v, num);
madSprite.transform.localPosition += (Vector3)v;
madSprite.guiDepth = depth++;
slotSprites.Add(madSprite);
}
if (TextureValid(textureIcon, atlasTextureIconGUID))
{
string text2 = string.Format("icon_{0:D2}", i + 1);
MadSprite madSprite2 = CreateHidden<MadSprite>(text2);
SetTexture(madSprite2, textureIcon, atlasTextureIconGUID);
madSprite2.transform.localPosition = zero;
madSprite2.transform.localEulerAngles = new Vector3(0f, 0f, num);
Vector2 v2 = LocalIconOffset(madSprite2.size);
v2 = RotateVector(v2, num);
madSprite2.transform.localPosition += (Vector3)v2;
madSprite2.guiDepth = depth++;
iconSprites.Add(madSprite2);
}
num += repeatRotationDelta;
Vector2 vector = RotateVector(repeatPositionDelta, num);
zero += vector;
}
return depth;
}
private Vector2 RotateVector(Vector2 v, float degrees)
{
float f = (float)Math.PI / 180f * degrees;
float num = Mathf.Cos(f);
float num2 = Mathf.Sin(f);
return new Vector2(v.x * num - v.y * num2, v.x * num2 + v.y * num);
}
private Vector2 LocalIconOffset(Vector2 iconSize)
{
Vector2 vector = new Vector2(iconSize.x / 2f, iconSize.y / 2f);
Vector2 vector2 = ComputeDrawAreaSize(iconSize);
float x = vector2.x;
float y = vector2.y;
float num = x / 2f;
float num2 = y / 2f;
switch (pivot)
{
case Pivot.Left:
return vector + new Vector2(0f, 0f - num2);
case Pivot.Top:
return vector + new Vector2(0f - num, 0f - y);
case Pivot.Right:
return vector + new Vector2(0f - x, 0f - num2);
case Pivot.Bottom:
return vector + new Vector2(0f - num, 0f);
case Pivot.TopLeft:
return vector + new Vector2(0f, 0f - y);
case Pivot.TopRight:
return vector + new Vector2(0f - x, 0f - y);
case Pivot.BottomRight:
return vector + new Vector2(0f - x, 0f);
case Pivot.BottomLeft:
return vector;
case Pivot.Center:
return vector + new Vector2(0f - num, 0f - num2);
default:
Debug.Log("Unknown pivot point: " + pivot);
return Vector2.zero;
}
}
private Vector2 ComputeDrawAreaSize(Vector2 iconSize)
{
return new Vector2(iconSize.x + repeatPositionDelta.x * (float)(repeatCount - 1), iconSize.y + repeatPositionDelta.y * (float)(repeatCount - 1));
}
}
}