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 slotSprites = new List(); private List iconSprites = new List(); 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 onIconShow; public event Action 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(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(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)); } } }