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(); for (int i = 0; i < createdChildren.Count; i++) { GameObject gameObject = createdChildren[i]; RectTransform component2 = gameObject.GetComponent(); 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("burn_bar"); imageBurn.type = Image.Type.Sliced; imageBurn.sprite = imageBurn.sprite ?? spriteBar; imageBurn.SetNativeSize(); } private void BuildBar() { imageBar = CreateChild("bar"); imageBar.type = Image.Type.Sliced; imageBar.sprite = spriteBar; imageBar.SetNativeSize(); } protected override Image.Type GetImageType() { return Image.Type.Sliced; } } }