Files
2026-02-21 16:45:37 +08:00

455 lines
12 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace EnergyBarToolkit
{
[RequireComponent(typeof(EnergyBar))]
[ExecuteInEditMode]
public class FilledRenderer3D : EnergyBar3DBase
{
public Texture2D textureBar;
public string atlasTextureBarGUID = string.Empty;
public ColorType textureBarColorType;
public Color textureBarColor = Color.white;
public Gradient textureBarGradient;
public GrowDirection growDirection;
public float radialOffset;
public float radialLength = 1f;
public bool effectBlink;
public float effectBlinkValue = 0.2f;
public float effectBlinkRatePerSecond = 1f;
public Color effectBlinkColor = new Color(1f, 1f, 1f, 0f);
public bool effectFollow;
public Object effectFollowObject;
public AnimationCurve effectFollowScaleX;
public AnimationCurve effectFollowScaleY;
public AnimationCurve effectFollowScaleZ;
public AnimationCurve effectFollowRotation;
public Gradient effectFollowColor;
[SerializeField]
private bool effectFollowDefaultsSet;
private MadSprite effectFollowSprite;
private int lastRebuildHash;
private bool dirty = true;
private MadSprite spriteBar;
private MadSprite spriteBurnBar;
private float _effectBlinkAccum;
public override Pivot pivot
{
get
{
return base.pivot;
}
set
{
bool flag = base.pivot != value;
base.pivot = value;
if (flag)
{
UpdatePivot();
}
}
}
public bool forceBlinking { get; set; }
private bool Blink { get; set; }
private Color BarColor
{
get
{
Color localColor = Color.white;
if (growDirection == GrowDirection.ColorChange)
{
localColor = textureBarGradient.Evaluate(base.energyBar.ValueF);
}
else
{
switch (textureBarColorType)
{
case ColorType.Solid:
localColor = textureBarColor;
break;
case ColorType.Gradient:
localColor = textureBarGradient.Evaluate(base.energyBar.ValueF);
break;
default:
MadDebug.Assert(false, "Unkwnown option: " + textureBarColorType);
break;
}
}
if (Blink)
{
localColor = effectBlinkColor;
}
return ComputeColor(localColor);
}
}
private Color BurnColor
{
get
{
Color localColor = effectBurnTextureBarColor;
if (Blink)
{
localColor = new Color(0f, 0f, 0f, 0f);
}
return ComputeColor(localColor);
}
}
public override Rect DrawAreaRect
{
get
{
if (spriteBar != null && spriteBar.CanDraw())
{
return spriteBar.GetBounds();
}
if (textureBar != null)
{
Vector2 vector = EnergyBar3DBase.PivotOffset(pivot);
float num = textureBar.width;
float num2 = textureBar.height;
return new Rect(vector.x * num, (1f - vector.y) * num2, num, num2);
}
return default(Rect);
}
}
protected override void OnEnable()
{
base.OnEnable();
if (!effectFollowDefaultsSet)
{
effectFollowScaleX = AnimationCurve.Linear(0f, 1f, 1f, 1f);
effectFollowScaleY = AnimationCurve.Linear(0f, 1f, 1f, 1f);
effectFollowScaleZ = AnimationCurve.Linear(0f, 1f, 1f, 1f);
effectFollowRotation = AnimationCurve.Linear(0f, 0f, 1f, 0f);
effectFollowDefaultsSet = true;
}
}
protected override void Update()
{
if (RebuildNeeded())
{
Rebuild();
}
base.Update();
UpdateBlinkEffect();
UpdateBar();
UpdatePivot();
UpdateFollowEffect();
}
private void UpdateBlinkEffect()
{
if (forceBlinking)
{
Blink = EnergyBarCommons.Blink(effectBlinkRatePerSecond, ref _effectBlinkAccum);
}
else if (effectBlink)
{
Blink = EnergyBarCommons.Blink(base.ValueF, effectBlinkValue, effectBlinkRatePerSecond, ref _effectBlinkAccum);
}
else
{
Blink = false;
}
}
private void UpdateBar()
{
bool visible = IsVisible();
if (effectBurn && spriteBurnBar != null)
{
spriteBurnBar.visible = visible;
spriteBurnBar.tint = BurnColor;
spriteBurnBar.fillValue = ValueFBurn;
spriteBurnBar.radialFillOffset = radialOffset;
spriteBurnBar.radialFillLength = radialLength;
}
if (spriteBar != null)
{
spriteBar.visible = visible;
spriteBar.tint = BarColor;
spriteBar.fillValue = ValueF2;
spriteBar.radialFillOffset = radialOffset;
spriteBar.radialFillLength = radialLength;
}
}
private void UpdatePivot()
{
MadSprite.PivotPoint pivotPoint = EnergyBar3DBase.Translate(pivot);
if (spriteBar != null)
{
spriteBar.pivotPoint = pivotPoint;
}
if (spriteBurnBar != null)
{
spriteBurnBar.pivotPoint = pivotPoint;
}
}
private void UpdateFollowEffect()
{
if (!effectFollow)
{
return;
}
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 (effectFollowSprite != null)
{
MadTransform.SetLocalPosition(effectFollowSprite.transform, EdgePosition());
MadTransform.SetLocalScale(effectFollowSprite.transform, new Vector3(x, y, z));
effectFollowSprite.tint = color;
Vector3 vector = new Vector3(0f, 0f, z2);
if (effectFollowSprite.transform.localEulerAngles != vector)
{
effectFollowSprite.transform.localEulerAngles = vector;
}
}
else if (effectFollowObject != null && effectFollowObject is GameObject)
{
Vector3 position = spriteBar.transform.TransformPoint(EdgePosition());
GameObject gameObject = effectFollowObject as GameObject;
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 vector2 = new Vector3(0f, 0f, z2);
if (gameObject.transform.localEulerAngles != vector2)
{
gameObject.transform.localEulerAngles = vector2;
}
}
}
private bool RebuildNeeded()
{
if (panel == null)
{
return false;
}
int currentHash = 37;
currentHash = MadHashCode.Add(currentHash, textureMode);
currentHash = EnergyBarBase.HashAdd(currentHash, panel);
currentHash = EnergyBarBase.HashAdd(currentHash, textureMode);
currentHash = EnergyBarBase.HashAddArray(currentHash, texturesBackground);
currentHash = EnergyBarBase.HashAddTexture(currentHash, textureBar);
currentHash = EnergyBarBase.HashAddArray(currentHash, texturesForeground);
currentHash = EnergyBarBase.HashAdd(currentHash, atlas);
currentHash = EnergyBarBase.HashAddArray(currentHash, atlasTexturesBackground);
currentHash = EnergyBarBase.HashAdd(currentHash, atlasTextureBarGUID);
currentHash = EnergyBarBase.HashAddArray(currentHash, atlasTexturesForeground);
currentHash = EnergyBarBase.HashAdd(currentHash, guiDepth);
currentHash = EnergyBarBase.HashAdd(currentHash, growDirection);
currentHash = EnergyBarBase.HashAdd(currentHash, effectBurn);
currentHash = EnergyBarBase.HashAddTexture(currentHash, effectBurnTextureBar);
currentHash = EnergyBarBase.HashAdd(currentHash, atlasEffectBurnTextureBarGUID);
currentHash = EnergyBarBase.HashAdd(currentHash, labelEnabled);
currentHash = EnergyBarBase.HashAdd(currentHash, labelFont);
currentHash = EnergyBarBase.HashAdd(currentHash, effectFollow);
currentHash = EnergyBarBase.HashAdd(currentHash, premultipliedAlpha);
currentHash = ((!(effectFollowObject != null) || !(effectFollowObject is Texture)) ? EnergyBarBase.HashAdd(currentHash, effectFollowObject) : EnergyBarBase.HashAddTexture(currentHash, effectFollowObject as Texture));
if (currentHash != lastRebuildHash || dirty)
{
lastRebuildHash = currentHash;
dirty = false;
return true;
}
return false;
}
protected override void Rebuild()
{
base.Rebuild();
List<MadSprite> list = MadTransform.FindChildren(base.transform, (MadSprite s) => s.gameObject.hideFlags == HideFlags.HideInHierarchy);
for (int num = 0; num < list.Count; num++)
{
MadGameObject.SafeDestroy(list[num].gameObject);
}
int depth = guiDepth * 32;
depth = BuildBackgroundTextures(depth);
if (textureBar != null)
{
if (effectBurn)
{
spriteBurnBar = CreateHidden<MadSprite>("bar_effect_burn");
spriteBurnBar.guiDepth = depth++;
if (TextureValid(effectBurnTextureBar, atlasEffectBurnTextureBarGUID))
{
SetTexture(spriteBurnBar, effectBurnTextureBar, atlasEffectBurnTextureBarGUID);
}
else
{
SetTexture(spriteBurnBar, textureBar, atlasTextureBarGUID);
}
spriteBurnBar.fillType = ToFillType(growDirection);
spriteBurnBar.radialFillOffset = radialOffset;
spriteBurnBar.radialFillLength = radialLength;
}
spriteBar = CreateHidden<MadSprite>("bar");
spriteBar.guiDepth = depth++;
SetTexture(spriteBar, textureBar, atlasTextureBarGUID);
spriteBar.fillType = ToFillType(growDirection);
spriteBar.radialFillOffset = radialOffset;
spriteBar.radialFillLength = radialLength;
}
depth = BuildForegroundTextures(depth);
if (effectFollow && effectFollowObject != null && effectFollowObject is Texture2D)
{
effectFollowSprite = CreateHidden<MadSprite>("bar_effect_follow");
effectFollowSprite.texture = effectFollowObject as Texture2D;
effectFollowSprite.guiDepth = depth++;
}
depth = RebuildLabel(depth);
UpdateContainer();
}
private MadSprite.FillType ToFillType(GrowDirection growDirection)
{
switch (growDirection)
{
case GrowDirection.LeftToRight:
return MadSprite.FillType.LeftToRight;
case GrowDirection.RightToLeft:
return MadSprite.FillType.RightToLeft;
case GrowDirection.TopToBottom:
return MadSprite.FillType.TopToBottom;
case GrowDirection.BottomToTop:
return MadSprite.FillType.BottomToTop;
case GrowDirection.ExpandHorizontal:
return MadSprite.FillType.ExpandHorizontal;
case GrowDirection.ExpandVertical:
return MadSprite.FillType.ExpandVertical;
case GrowDirection.RadialCW:
return MadSprite.FillType.RadialCW;
case GrowDirection.RadialCCW:
return MadSprite.FillType.RadialCCW;
case GrowDirection.ColorChange:
return MadSprite.FillType.None;
default:
MadDebug.Assert(false, "Unkwnown grow direction: " + growDirection);
return MadSprite.FillType.None;
}
}
public bool GrowDirectionSupportedByFollowEffect(GrowDirection growDirection)
{
switch (growDirection)
{
case GrowDirection.LeftToRight:
case GrowDirection.RightToLeft:
case GrowDirection.BottomToTop:
case GrowDirection.TopToBottom:
return true;
default:
return false;
}
}
private Vector2 EdgePosition()
{
if (spriteBar == null)
{
return Vector2.zero;
}
float num = spriteBar.liveLeft * spriteBar.size.x;
float num2 = spriteBar.liveRight * spriteBar.size.x;
float num3 = spriteBar.liveTop * spriteBar.size.y;
float num4 = spriteBar.liveBottom * spriteBar.size.y;
float num5 = num2 - num;
float num6 = num3 - num4;
float x = num + num5 / 2f;
float y = num4 + num6 / 2f;
Vector2 vector;
switch (growDirection)
{
case GrowDirection.LeftToRight:
vector = new Vector2(num + num5 * ValueF2, y);
break;
case GrowDirection.RightToLeft:
vector = new Vector2(num + num5 * (1f - ValueF2), y);
break;
case GrowDirection.BottomToTop:
vector = new Vector2(x, num4 + num6 * (1f - ValueF2));
break;
case GrowDirection.TopToBottom:
vector = new Vector2(x, num4 + num6 * ValueF2);
break;
default:
vector = Vector2.zero;
break;
}
Vector2 vector2 = ComputeOffset();
return new Vector2(vector.x - vector2.x, 0f - vector.y + vector2.y);
}
private Vector2 ComputeOffset()
{
Rect drawAreaRect = DrawAreaRect;
switch (pivot)
{
case Pivot.Left:
return new Vector2(0f, drawAreaRect.height / 2f);
case Pivot.Top:
return new Vector2(drawAreaRect.width / 2f, 0f);
case Pivot.Right:
return new Vector2(drawAreaRect.width, drawAreaRect.height / 2f);
case Pivot.Bottom:
return new Vector2(drawAreaRect.width / 2f, drawAreaRect.height);
case Pivot.TopLeft:
return Vector2.zero;
case Pivot.TopRight:
return new Vector2(drawAreaRect.width, 0f);
case Pivot.BottomRight:
return new Vector2(drawAreaRect.width, drawAreaRect.height);
case Pivot.BottomLeft:
return new Vector2(0f, drawAreaRect.height);
case Pivot.Center:
return new Vector2(drawAreaRect.width / 2f, drawAreaRect.height / 2f);
default:
Debug.LogError("Unknown pivot: " + pivot);
return Vector2.zero;
}
}
}
}