using System; using UnityEngine; using UnityEngine.Serialization; using UnityEngine.UI; namespace EnergyBarToolkit { [RequireComponent(typeof(EnergyBar))] [SelectionBase] [ExecuteInEditMode] public class FilledRendererUGUI : EnergyBarUGUIBase { public enum BlinkOperator { LessThan = 0, LessOrEqual = 1, GreaterThan = 2, GreaterOrEqual = 3 } public Sprite spriteBar; public Material spriteBarMaterial; public ColorType spriteBarColorType; public Color spriteBarColor = Color.white; public Gradient spriteBarGradient; public GrowDirection growDirection; public float radialOffset; public float radialLength = 1f; public Vector3 barImageScale = new Vector3(1f, 1f, 1f); public Vector3 barImageOffset = new Vector3(0f, 0f, 0f); public Vector2 barImageRepeater = new Vector2(1f, 1f); 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; public bool effectFollow; public GameObject effectFollowObject; public Vector3 effectFollowOffset = Vector3.zero; public AnimationCurve effectFollowScaleX = AnimationCurve.Linear(0f, 1f, 1f, 1f); public AnimationCurve effectFollowScaleY = AnimationCurve.Linear(0f, 1f, 1f, 1f); public AnimationCurve effectFollowScaleZ = AnimationCurve.Linear(0f, 1f, 1f, 1f); public AnimationCurve effectFollowRotation = AnimationCurve.Linear(0f, 0f, 1f, 0f); public Gradient effectFollowColor; public bool effectTiled; public Sprite effectTiledSprite; public Vector2 effectTiledTiling = new Vector2(2f, 2f); public Vector2 effectTiledStartOffset = new Vector2(0f, 0f); public Vector2 effectTiledOffsetChangeSpeed = new Vector2(-1f, 0f); public Color effectTiledTint = Color.white; [SerializeField] private Image2 effectTilledImageBarMask; [SerializeField] private Image2 effectTilledImageTiles; [SerializeField] private int lastRebuildHash; [SerializeField] private bool dirty; [FormerlySerializedAs("barImage")] [SerializeField] private Image2 imageBar; [FormerlySerializedAs("burnImage")] [SerializeField] private Image2 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(); UpdateTiledEffect(); UpdateFollowEffect(); UpdateColor(); UpdateRadialOffset(); } 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 (effectTilledImageBarMask != null) { MadTransform.SetLocalScale(effectTilledImageBarMask.transform, barImageScale); MadTransform.SetLocalPosition(effectTilledImageBarMask.transform, localPosition); } } } private void UpdateTiledEffect() { if (effectTiled) { if (effectTilledImageTiles.uvTiling != effectTiledTiling) { effectTilledImageTiles.uvTiling = effectTiledTiling; effectTilledImageTiles.SetVerticesDirty(); } effectTilledImageTiles.color = effectTiledTint; if (Application.isPlaying) { effectTilledImageTiles.uvOffset += effectTiledOffsetChangeSpeed * Time.deltaTime; effectTilledImageTiles.SetVerticesDirty(); } else if (effectTilledImageTiles.uvOffset != effectTiledStartOffset) { effectTilledImageTiles.uvOffset = effectTiledStartOffset; effectTilledImageTiles.SetVerticesDirty(); } } } private void UpdateValue() { if (!(imageBar == null)) { imageBar.fillValue = ValueF2; imageBar.SetAllDirty(); if (effectTilledImageBarMask != null) { effectTilledImageBarMask.fillValue = ValueF2; effectTilledImageBarMask.SetAllDirty(); } } } 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(); imageBurn.fillValue = ValueFBurn; } } private void UpdateFollowEffect() { if (!effectFollow) { return; } UpdateEffectFollowDefaults(); Color color = effectFollowColor.Evaluate(ValueF2); float x = effectFollowScaleX.Evaluate(ValueF2); float y = effectFollowScaleY.Evaluate(ValueF2); float z = effectFollowScaleZ.Evaluate(ValueF2); float z2 = effectFollowRotation.Evaluate(ValueF2) * 360f; if (effectFollowObject != null) { Vector3 position = imageBar.transform.TransformPoint(EdgePosition()); GameObject gameObject = effectFollowObject; MadTransform.SetPosition(gameObject.transform, position); MadTransform.SetLocalScale(gameObject.transform, new Vector3(x, y, z)); if (gameObject.GetComponent() != null) { gameObject.GetComponent().sharedMaterial.color = color; } Vector3 vector = new Vector3(0f, 0f, z2); if (gameObject.transform.localEulerAngles != vector) { gameObject.transform.localEulerAngles = vector; } Graphic component = gameObject.GetComponent(); if ((bool)component) { component.color = color; } } } private void UpdateEffectFollowDefaults() { if (effectFollowScaleX.length == 0) { effectFollowScaleX = AnimationCurve.Linear(0f, 1f, 1f, 1f); } if (effectFollowScaleY.length == 0) { effectFollowScaleY = AnimationCurve.Linear(0f, 1f, 1f, 1f); } if (effectFollowScaleZ.length == 0) { effectFollowScaleZ = AnimationCurve.Linear(0f, 1f, 1f, 1f); } if (effectFollowRotation.length == 0) { effectFollowRotation = AnimationCurve.Linear(0f, 0f, 1f, 0f); } } private Vector2 EdgePosition() { if (spriteBar == null) { return Vector2.zero; } Vector4 drawingDimensions = imageBar.GetDrawingDimensions(false); float x = drawingDimensions.x; float z = drawingDimensions.z; float y = drawingDimensions.y; float w = drawingDimensions.w; float num = z - x; float num2 = w - y; float x2 = x + num / 2f; float y2 = y + num2 / 2f; Vector2 vector; switch (growDirection) { case GrowDirection.LeftToRight: vector = new Vector2(x + num * ValueF2, y2); break; case GrowDirection.RightToLeft: vector = new Vector2(x + num * ValueF2, y2); break; case GrowDirection.BottomToTop: vector = new Vector2(x2, y + num2 * ValueF2); break; case GrowDirection.TopToBottom: vector = new Vector2(x2, y + num2 * ValueF2); break; default: vector = Vector2.zero; break; } return new Vector2(vector.x + effectFollowOffset.x, vector.y + effectFollowOffset.y); } 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; if (effectTiled) { effectTilledImageTiles.color = EnergyBarBase.Multiply(new Color(1f, 1f, 1f, color.a), effectTiledTint); } } private void UpdateRadialOffset() { if (!(imageBar == null)) { imageBar.radialFillOffset = radialOffset; imageBar.radialFillLength = radialLength; if ((bool)imageBurn) { imageBurn.radialFillOffset = radialOffset; imageBurn.radialFillLength = radialLength; } } } 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.Add(currentHash, (spriteBarMaterial != null) ? spriteBarMaterial.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); currentHash = MadHashCode.Add(currentHash, effectTiled); currentHash = MadHashCode.Add(currentHash, effectTiledSprite); currentHash = MadHashCode.Add(currentHash, barImageRepeater); if (currentHash != lastRebuildHash || dirty) { lastRebuildHash = currentHash; dirty = false; return true; } return false; } public void Rebuild() { RemoveCreatedChildren(); BuildBackgroundImages(); if (effectBurn) { BuildBurnBar(); } BuildBar(); if (effectTiled) { BuildEffectTilled(); } BuildForegroundImages(); UpdateSize(); MoveLabelToTop(); } private void BuildBurnBar() { imageBurn = CreateChild("burn_bar"); if ((bool)effectBurnSprite.sprite) { imageBurn.sprite = effectBurnSprite.sprite; } else { imageBurn.sprite = spriteBar; } imageBurn.material = effectBurnSprite.material; imageBurn.SetNativeSize(); imageBurn.growDirection = growDirection; imageBurn.uvTiling = barImageRepeater; } private void BuildBar() { imageBar = CreateChild("bar"); imageBar.sprite = spriteBar; imageBar.material = spriteBarMaterial; imageBar.SetNativeSize(); imageBar.growDirection = growDirection; imageBar.readable = true; imageBar.uvTiling = barImageRepeater; } private void BuildEffectTilled() { effectTilledImageBarMask = CreateChild("bar_mask"); effectTilledImageBarMask.sprite = spriteBar; effectTilledImageBarMask.SetNativeSize(); effectTilledImageBarMask.growDirection = growDirection; effectTilledImageBarMask.readable = true; Mask mask = effectTilledImageBarMask.gameObject.AddComponent(); mask.showMaskGraphic = false; effectTilledImageTiles = CreateChild("tiles", effectTilledImageBarMask.transform); effectTilledImageTiles.sprite = effectTiledSprite; } } }