using UnityEngine; namespace EnergyBarToolkit { [ExecuteInEditMode] [RequireComponent(typeof(EnergyBar))] public class TransformRenderer3D : EnergyBar3DBase { public Texture2D objectTexture; public string objectAtlasTextureGUID; public Color objectTint = Color.white; public Vector2 objectAnchor = new Vector2(0.5f, 0.5f); public bool transformTranslate; public bool transformRotate; public bool transformScale; public TranslateFunction translateFunction = new TranslateFunction(); public RotateFunction rotateFunction = new RotateFunction(); public ScaleFunction scaleFunction = new ScaleFunction(); private int lastRebuildHash; private bool dirty = true; private MadSprite objectSprite; public override Rect DrawAreaRect { get { Rect result = AnyBackgroundOrForegroundSpriteSize(); if (result.width == 0f && objectSprite != null && objectSprite.CanDraw()) { result = objectSprite.GetTransformedBounds(); } return result; } } protected override void Start() { base.Start(); if (RebuildNeeded()) { Rebuild(); } } protected override void Update() { base.Update(); if (RebuildNeeded()) { Rebuild(); } if (!(panel == null)) { UpdateColor(); UpdateTransform(); } } private void UpdateColor() { if (objectSprite != null) { objectSprite.tint = ComputeColor(objectTint); } } private void UpdateTransform() { if (transformTranslate) { Vector2 vector = translateFunction.Value(ValueF2); Rect bounds = objectSprite.GetBounds(); objectSprite.transform.localPosition = new Vector2(vector.x * bounds.width, vector.y * bounds.height); } if (transformRotate) { Quaternion rotation = rotateFunction.Value(ValueF2); objectSprite.transform.localRotation = Quaternion.identity * Quaternion.Inverse(rotation); } if (transformScale) { Vector3 localScale = scaleFunction.Value(ValueF2); objectSprite.transform.localScale = localScale; } } private bool RebuildNeeded() { if (panel == null) { return false; } MadHashCode madHashCode = new MadHashCode(); madHashCode.Add(textureMode); madHashCode.Add(atlas); madHashCode.Add(objectTexture); madHashCode.Add(objectAtlasTextureGUID); madHashCode.Add(objectAnchor); madHashCode.AddEnumerable(texturesBackground); madHashCode.AddEnumerable(atlasTexturesBackground); madHashCode.AddEnumerable(texturesForeground); madHashCode.AddEnumerable(atlasTexturesForeground); madHashCode.Add(transformTranslate); madHashCode.Add(transformRotate); madHashCode.Add(transformScale); madHashCode.Add(translateFunction); madHashCode.Add(rotateFunction); madHashCode.Add(scaleFunction); madHashCode.Add(labelEnabled); madHashCode.Add(labelFont); madHashCode.Add(premultipliedAlpha); int hashCode = madHashCode.GetHashCode(); if (hashCode != lastRebuildHash || dirty) { lastRebuildHash = hashCode; dirty = false; return true; } return false; } protected override void Rebuild() { base.Rebuild(); if (objectSprite != null) { MadGameObject.SafeDestroy(objectSprite.gameObject); } int depth = guiDepth * 32; depth = BuildBackgroundTextures(depth); depth = BuildObject(depth); depth = BuildForegroundTextures(depth); depth = RebuildLabel(depth); UpdateContainer(); } private int BuildObject(int nextDepth) { objectSprite = CreateHidden("object"); objectSprite.guiDepth = nextDepth++; SetTexture(objectSprite, objectTexture, objectAtlasTextureGUID); objectSprite.pivotPoint = MadSprite.PivotPoint.Custom; objectSprite.customPivotPoint = new Vector2(objectAnchor.x, 1f - objectAnchor.y); return nextDepth; } } }