using System; using UnityEngine; namespace EnergyBarToolkit { [ExecuteInEditMode] [RequireComponent(typeof(EnergyBar))] public class EnergyBarRenderer : EnergyBarOnGUIBase { public enum RotatePoint { VisibleAreaCenter = 0, TextureCenter = 1, CustomPoint = 2 } public class BadTextureException : Exception { public BadTextureException() { } public BadTextureException(string message) : base(message) { } } public delegate void EdgeEffectFunction(Vector2 edgePosition); public static readonly Color Transparent = new Color(1f, 1f, 1f, 0f); public Vector2 screenPosition = new Vector2(10f, 10f); public bool screenPositionNormalized; public Vector2 size = new Vector2(100f, 20f); private Vector2 sizeReal; private Vector2 screenPositionReal; public Texture2D textureBackground; public Color textureBackgroundColor = Color.white; public Texture2D textureBar; private Texture2D _textureBar; public ColorType textureBarColorType; public Color textureBarColor = Color.white; public Gradient textureBarGradient; public Texture2D textureForeground; public Color textureForegroundColor = Color.white; public GrowDirection growDirection; public RotatePoint radialRotatePoint; public Vector2 radialCustomCenter; public float radialOffset; public float radialLength = 1f; private Rect textureBarVisibleBounds; private Rect textureBarVisibleBoundsOrig; public bool effectBlink; public float effectBlinkValue = 0.2f; public float effectBlinkRatePerSecond = 1f; public Color effectBlinkColor = new Color(1f, 1f, 1f, 0f); private float effectBlinkAccum; private bool effectBlinkVisible; public bool effectEdge; public Texture2D effectEdgeTexture; public float effectEdgeIn = 0.2f; public float effectEdgeOut = 0.2f; public float effectEdgeRotateAngle = 100f; public EdgeEffectFunction edgeEffectFunction; [SerializeField] private bool sizeNormalized; [SerializeField] private bool screenPositionCalculateSize = true; private Vector2 ScreenPositionPixels { get { if (screenPositionNormalized) { return new Vector2(screenPosition.x * (float)Screen2.width, screenPosition.y * (float)Screen2.height); } return screenPosition; } } public override Vector2 SizePixels { get { return GetSizePixels(size); } set { SetSizePixels(ref size, value); } } public override Vector2 TextureSizePixels { get { if (textureBar == null) { return Vector2.one; } return new Vector2(textureBar.width, textureBar.height); } } public override Rect DrawAreaRect { get { return new Rect(screenPositionReal.x, screenPositionReal.y, sizeReal.x, sizeReal.y); } } private void OnValidate() { effectEdgeIn = Mathf.Clamp01(effectEdgeIn); effectEdgeOut = Mathf.Clamp01(effectEdgeOut); } protected override void OnEnable() { base.OnEnable(); edgeEffectFunction = GUIDrawEdgeEffectFun; } protected override void Start() { base.Start(); if (version == 169) { Upgrade_169_171(); } if (texturesBackground.Length == 0 && textureBackground != null) { Array.Resize(ref texturesBackground, 1); Tex tex = new Tex(); tex.texture = textureBackground; tex.color = textureBackgroundColor; texturesBackground[0] = tex; textureBackground = null; } if (texturesForeground.Length == 0 && textureForeground != null) { Array.Resize(ref texturesForeground, 1); Tex tex2 = new Tex(); tex2.texture = textureForeground; tex2.color = textureForegroundColor; texturesForeground[0] = tex2; textureForeground = null; } } private void Upgrade_169_171() { if (sizeNormalized) { resizeMode = ResizeMode.Stretch; } else if (!screenPositionCalculateSize) { resizeMode = ResizeMode.Fixed; } version = 171; } private void UpdateSize() { sizeReal = Round(SizePixels); screenPositionReal = RealPosition(Round(ScreenPositionPixels), SizePixels); } protected override void Update() { base.Update(); UpdateSize(); if (!IsValid()) { return; } if (textureBar != _textureBar) { textureBarVisibleBoundsOrig = FindBounds(textureBar); if (textureBarVisibleBoundsOrig.width == 0f) { return; } textureBarVisibleBounds = textureBarVisibleBoundsOrig; _textureBar = textureBar; } if (effectBlink) { effectBlinkVisible = EnergyBarCommons.Blink(base.energyBar.ValueF, effectBlinkValue, effectBlinkRatePerSecond, ref effectBlinkAccum); } } private bool IsValid() { return textureBar != null; } public new void OnGUI() { base.OnGUI(); if (RepaintPhase() && IsVisible() && IsValid()) { UpdateSize(); GUIDrawBackground(); if (effectBurn && ValueFBurn != 0f) { Texture2D texture = ((!(effectBurnTextureBar != null)) ? textureBar : effectBurnTextureBar); DrawBar(ValueFBurn, GetTextureBurnColor(), texture); } if (ValueF2 != 0f) { DrawBar(ValueF2, GetTextureBarColor(), textureBar); } GUIDrawForeground(); GUIDrawEdgeEffect(); GUIDrawLabel(); } } private Color GetTextureBarColor() { if (effectBlink && effectBlinkVisible) { return effectBlinkColor; } if (growDirection == GrowDirection.ColorChange) { return textureBarGradient.Evaluate(base.energyBar.ValueF); } switch (textureBarColorType) { case ColorType.Solid: return textureBarColor; case ColorType.Gradient: return textureBarGradient.Evaluate(base.energyBar.ValueF); default: Debug.LogError("Unknown texture bar type! This is a bug! Please report this."); return Color.white; } } private Color GetTextureBurnColor() { if (effectBlink && effectBlinkVisible) { return Transparent; } return effectBurnTextureBarColor; } private void DrawBar(float value, Color color, Texture2D texture) { Rect rect = new Rect(screenPositionReal.x, screenPositionReal.y, sizeReal.x, sizeReal.y); Rect visibleRect = textureBarVisibleBounds; switch (growDirection) { case GrowDirection.LeftToRight: DrawTextureHorizFill(rect, texture, visibleRect, color, false, value); break; case GrowDirection.RightToLeft: DrawTextureHorizFill(rect, texture, visibleRect, color, true, value); break; case GrowDirection.TopToBottom: DrawTextureVertFill(rect, texture, visibleRect, color, false, value); break; case GrowDirection.BottomToTop: DrawTextureVertFill(rect, texture, visibleRect, color, true, value); break; case GrowDirection.RadialCW: DrawTextureRadialFill(rect, texture, color, false, value, radialOffset, radialLength); break; case GrowDirection.RadialCCW: DrawTextureRadialFill(rect, texture, color, true, value, radialOffset, radialLength); break; case GrowDirection.ExpandHorizontal: DrawTextureExpandFill(rect, texture, visibleRect, color, false, value); break; case GrowDirection.ExpandVertical: DrawTextureExpandFill(rect, texture, visibleRect, color, true, value); break; case GrowDirection.ColorChange: DrawTexture(rect, texture, color); break; default: Debug.LogError("Unknown grow direction: " + growDirection); break; } } private Rect TexCoordsForEnergyBar(Rect energyBounds) { Vector2 vector = screenPositionReal; Vector2 vector2 = sizeReal; switch (growDirection) { case GrowDirection.LeftToRight: return new Rect(0f, 0f, (energyBounds.xMax - vector.x) / vector2.x, 1f); case GrowDirection.RightToLeft: { float num3 = (energyBounds.xMin - vector.x) / vector2.x; float width = 1f - num3; return new Rect(num3, 0f, width, 1f); } case GrowDirection.BottomToTop: { float num2 = (energyBounds.yMin - vector.y) / vector2.y; float height = 1f - num2; return new Rect(0f, 0f, 1f, height); } case GrowDirection.TopToBottom: { float num = (energyBounds.yMax - vector.y) / vector2.y; return new Rect(0f, 1f - num, 1f, num); } default: MadDebug.Assert(false, "Unknown grow direction " + growDirection); return default(Rect); } } private Rect toAbsolute(Rect rect) { return new Rect(rect.x + screenPositionReal.x, rect.y + screenPositionReal.y, rect.width, rect.height); } private void GUIDrawEdgeEffect() { if (effectEdge && !(effectEdgeTexture == null)) { Vector2 edgePosition = EdgePosition(); edgeEffectFunction(edgePosition); } } private void GUIDrawEdgeEffectFun(Vector2 position) { float num = effectEdgeTexture.width / 2; float num2 = effectEdgeTexture.height / 2; Rect rect = new Rect(position.x - num, position.y - num2, num * 2f, num2 * 2f); float a = ((ValueF2 < effectEdgeIn) ? (ValueF2 / effectEdgeIn) : ((!(1f - ValueF2 < effectEdgeOut)) ? 1f : ((1f - ValueF2) / effectEdgeOut))); Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.TRS(new Vector3(0f - position.x, 0f - position.y, 0f), Quaternion.identity, Vector3.one) * GUI.matrix; GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(ValueF2 * effectEdgeRotateAngle, Vector3.forward), Vector3.one) * GUI.matrix; GUI.matrix = Matrix4x4.TRS(new Vector3(position.x, position.y, 0f), Quaternion.identity, Vector3.one) * GUI.matrix; DrawTexture(tint: new Color(1f, 1f, 1f, a), rect: rect, texture: effectEdgeTexture); GUI.matrix = matrix; } private Vector2 EdgePosition() { Rect rect = textureBarVisibleBounds; if (growDirection == GrowDirection.LeftToRight) { return screenPositionReal + new Vector2((rect.xMin + rect.width * ValueF2) * sizeReal.x, (1f - (rect.yMin + rect.height / 2f)) * sizeReal.y); } return Vector2.zero; } } }