534 lines
13 KiB
C#
534 lines
13 KiB
C#
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<RectTransform>();
|
|
for (int i = 0; i < createdChildren.Count; i++)
|
|
{
|
|
GameObject gameObject = createdChildren[i];
|
|
RectTransform component2 = gameObject.GetComponent<RectTransform>();
|
|
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<Renderer>() != null)
|
|
{
|
|
gameObject.GetComponent<Renderer>().sharedMaterial.color = color;
|
|
}
|
|
Vector3 vector = new Vector3(0f, 0f, z2);
|
|
if (gameObject.transform.localEulerAngles != vector)
|
|
{
|
|
gameObject.transform.localEulerAngles = vector;
|
|
}
|
|
Graphic component = gameObject.GetComponent<Graphic>();
|
|
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<Image2>("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<Image2>("bar");
|
|
imageBar.sprite = spriteBar;
|
|
imageBar.material = spriteBarMaterial;
|
|
imageBar.SetNativeSize();
|
|
imageBar.growDirection = growDirection;
|
|
imageBar.readable = true;
|
|
imageBar.uvTiling = barImageRepeater;
|
|
}
|
|
|
|
private void BuildEffectTilled()
|
|
{
|
|
effectTilledImageBarMask = CreateChild<Image2>("bar_mask");
|
|
effectTilledImageBarMask.sprite = spriteBar;
|
|
effectTilledImageBarMask.SetNativeSize();
|
|
effectTilledImageBarMask.growDirection = growDirection;
|
|
effectTilledImageBarMask.readable = true;
|
|
Mask mask = effectTilledImageBarMask.gameObject.AddComponent<Mask>();
|
|
mask.showMaskGraphic = false;
|
|
effectTilledImageTiles = CreateChild<Image2>("tiles", effectTilledImageBarMask.transform);
|
|
effectTilledImageTiles.sprite = effectTiledSprite;
|
|
}
|
|
}
|
|
}
|