using System; using System.Collections.Generic; using UnityEngine; namespace EnergyBarToolkit { public abstract class EnergyBar3DBase : EnergyBarBase { public new enum Pivot { Left = 0, Top = 1, Right = 2, Bottom = 3, TopLeft = 4, TopRight = 5, BottomRight = 6, BottomLeft = 7, Center = 8 } public enum BarType { Filled = 0, Repeated = 1, Sequence = 2, Transform = 3 } public enum TextureMode { Textures = 0, TextureAtlas = 1 } public enum LookAtMode { Disabled = 0, CustomObject = 1, MainCamera = 2 } [Serializable] public class AtlasTex : AbstractTex { public string spriteGUID = string.Empty; public bool Valid { get { return !string.IsNullOrEmpty(spriteGUID); } } public override int GetHashCode() { int currentHash = 37; currentHash = MadHashCode.Add(currentHash, spriteGUID); return MadHashCode.Add(currentHash, color); } } public const int DepthSpace = 32; public MadPanel panel; public bool premultipliedAlpha; public int guiDepth = 1; public GameObject anchorObject; public Camera anchorCamera; public TextureMode textureMode; public Tex[] texturesBackground = new Tex[0]; public Tex[] texturesForeground = new Tex[0]; public MadAtlas atlas; public AtlasTex[] atlasTexturesBackground = new AtlasTex[0]; public AtlasTex[] atlasTexturesForeground = new AtlasTex[0]; public LookAtMode lookAtMode; public GameObject lookAtObject; public MadFont labelFont; public float labelScale = 32f; public Pivot labelPivot = Pivot.Center; public bool editorSelectable = true; [SerializeField] private bool underThePanel = true; private MadText labelSprite; private List spriteObjectsBg = new List(); private List spriteObjectsFg = new List(); private List hiddenObjects = new List(); [SerializeField] private Pivot _pivot = Pivot.Center; private Transform anchorParentCache; private MadAnchor anchorCache; private Transform container; protected bool useAtlas { get { return textureMode == TextureMode.TextureAtlas; } } public virtual Pivot pivot { get { return _pivot; } set { _pivot = value; } } protected override void OnEnable() { base.OnEnable(); EnableAllHidden(); } protected override void Start() { base.Start(); ReconnectPanelIfNeeded(true); } protected override void OnDisable() { base.OnDisable(); DisableAllHidden(); } protected virtual void OnDestroy() { DestroyAllHidden(true); } protected override void Update() { base.Update(); ReconnectPanelIfNeeded(false); UpdatePanelInfo(); UpdateContainer(); UpdateLabel(); UpdateAnchor(); UpdateColors(); UpdatePivot(); UpdateLookAt(); } protected void UpdateContainer() { if (container != null) { ApplyTransform(container); } } private void UpdateLabel() { if (!(labelSprite == null)) { labelSprite.scale = labelScale; labelSprite.pivotPoint = Translate(labelPivot); labelSprite.transform.localPosition = base.LabelPositionPixels; labelSprite.text = LabelFormatResolve(labelFormat); labelSprite.tint = ComputeColor(labelColor); } } private void UpdateAnchor() { if (base.transform.parent != anchorParentCache) { anchorParentCache = base.transform.parent; if (anchorParentCache != null) { anchorCache = anchorParentCache.GetComponent(); } else { anchorCache = null; } } if (anchorCache != null) { anchorObject = anchorCache.anchorObject; anchorCamera = anchorCache.anchorCamera; } else { anchorObject = null; anchorCamera = null; } } private void UpdateColors() { if (textureMode == TextureMode.Textures) { UpdateTextureColors(spriteObjectsBg, texturesBackground); UpdateTextureColors(spriteObjectsFg, texturesForeground); } else { UpdateTextureColors(spriteObjectsBg, atlasTexturesBackground); UpdateTextureColors(spriteObjectsFg, atlasTexturesForeground); } } private void UpdateTextureColors(List sprites, AbstractTex[] textures) { if (sprites.Count != textures.Length) { return; } for (int i = 0; i < sprites.Count; i++) { MadSprite madSprite = sprites[i]; AbstractTex abstractTex = textures[i]; if (!(madSprite == null)) { madSprite.visible = IsVisible(); madSprite.tint = ComputeColor(abstractTex.color); } } } private void UpdatePivot() { MadSprite.PivotPoint pivotPoint = Translate(pivot); for (int i = 0; i < spriteObjectsBg.Count; i++) { MadSprite madSprite = spriteObjectsBg[i]; if (madSprite != null) { madSprite.pivotPoint = pivotPoint; } } for (int j = 0; j < spriteObjectsFg.Count; j++) { MadSprite madSprite2 = spriteObjectsFg[j]; if (madSprite2 != null) { madSprite2.pivotPoint = pivotPoint; } } } private void UpdateLookAt() { Transform transform; switch (lookAtMode) { case LookAtMode.Disabled: return; case LookAtMode.CustomObject: if (lookAtObject != null) { transform = lookAtObject.transform; break; } return; case LookAtMode.MainCamera: { Camera main = Camera.main; if (main != null) { transform = main.transform; break; } Debug.LogWarning("Cannot find camera tagged as MainCamera. Plase make sure that there is one.", this); return; } default: Debug.LogError("Unknown option: " + lookAtMode); return; } base.transform.LookAt(base.transform.position + (base.transform.position - transform.position)); } private void ReconnectPanelIfNeeded(bool firstTime) { if (!(panel == null)) { return; } panel = MadPanel.FirstOrNull(base.transform); if (panel == null && firstTime) { Debug.LogError("You have to initialize scene first! Please execute Tools -> Energy Bar Toolkit -> Initialize"); return; } MadPanel madPanel = MadTransform.FindParent(base.transform); bool flag = madPanel == panel; if (flag && !underThePanel) { base.transform.localScale /= panel.transform.lossyScale.x; } else if (!flag && underThePanel) { base.transform.localScale *= panel.transform.lossyScale.x; } underThePanel = flag; } private void UpdatePanelInfo() { if (panel != null && Application.isEditor && !Application.isPlaying) { MadPanel madPanel = MadTransform.FindParent(base.transform); bool flag = madPanel == panel; underThePanel = flag; } } private void EnableAllHidden() { for (int i = 0; i < hiddenObjects.Count; i++) { hiddenObjects[i].SetActive(true); } if (container != null) { container.gameObject.SetActive(true); } } private void DisableAllHidden() { for (int i = 0; i < hiddenObjects.Count; i++) { hiddenObjects[i].SetActive(false); } if (container != null) { container.gameObject.SetActive(false); } } private void DestroyAllHidden(bool forceImmediate = false) { for (int i = 0; i < hiddenObjects.Count; i++) { DestroyHidden(hiddenObjects[i], forceImmediate); } hiddenObjects.Clear(); if (container != null) { DestroyHidden(container.gameObject, forceImmediate); container = null; } } protected virtual void Rebuild() { spriteObjectsBg.Clear(); spriteObjectsFg.Clear(); DestroyAllHidden(); List list = MadTransform.FindChildren(base.transform, (MadSprite s) => (s.hideFlags | HideFlags.HideInHierarchy) != HideFlags.None, 0); if (list.Count > 0) { Debug.Log("There were " + list.Count + " hidden unmanaged sprites under this bar. I will remove them."); for (int num = 0; num < list.Count; num++) { MadGameObject.SafeDestroy(list[num].gameObject); } } } protected int BuildBackgroundTextures(int depth) { if (useAtlas) { return BuildTextures(atlasTexturesBackground, "bg_", depth, ref spriteObjectsBg); } return BuildTextures(texturesBackground, "bg_", depth, ref spriteObjectsBg); } protected int BuildForegroundTextures(int depth) { if (useAtlas) { return BuildTextures(atlasTexturesForeground, "fg_", depth, ref spriteObjectsFg); } return BuildTextures(texturesForeground, "fg_", depth, ref spriteObjectsFg); } private int BuildTextures(T[] textures, string prefix, int startDepth, ref List sprites) { int num = 0; foreach (T val in textures) { Tex tex = val as Tex; AtlasTex atlasTex = val as AtlasTex; if ((tex == null || tex.Valid) && (atlasTex == null || atlasTex.Valid)) { string text = string.Format("_{0}{1:D2}", prefix, num + 1); MadSprite madSprite = CreateHidden(text); madSprite.guiDepth = startDepth + num; if (tex != null) { madSprite.texture = tex.texture; } else { madSprite.inputType = MadSprite.InputType.TextureAtlas; madSprite.textureAtlas = atlas; madSprite.textureAtlasSpriteGUID = atlasTex.spriteGUID; } madSprite.tint = ((tex == null) ? atlasTex.color : tex.color); ColorBind colorBind = madSprite.gameObject.AddComponent(); colorBind.tex = tex; sprites.Add(madSprite); num++; } } return startDepth + num; } protected int RebuildLabel(int depth) { if (labelEnabled && labelFont != null) { labelSprite = CreateHidden("_label"); labelSprite.font = labelFont; labelSprite.guiDepth = depth++; } UpdateLabel(); return depth; } public Rect AnyBackgroundOrForegroundSpriteSize() { MadSprite madSprite = null; if (spriteObjectsBg.Count > 0) { madSprite = spriteObjectsBg[0]; } if (madSprite == null && spriteObjectsFg.Count > 0) { madSprite = spriteObjectsFg[0]; } if (madSprite != null) { return madSprite.GetTransformedBounds(); } Texture2D texture2D = null; if (texturesBackground.Length > 0) { texture2D = texturesBackground[0].texture; } if (texture2D == null && texturesForeground.Length > 0) { texture2D = texturesForeground[0].texture; } if (texture2D != null) { Vector2 vector = PivotOffset(pivot); float num = texture2D.width; float num2 = texture2D.height; return new Rect(vector.x * num, (1f - vector.y) * num2, num, num2); } return default(Rect); } protected void ApplyTransform(Component c) { if (c != null) { ApplyTransform(c.gameObject); } } protected void ApplyTransform(GameObject go) { if (go != null) { go.transform.position = base.transform.position; go.transform.localScale = base.transform.lossyScale; go.transform.rotation = base.transform.rotation; } } protected void DestroyHidden(GameObject go, bool forceImmediate) { if (forceImmediate) { UnityEngine.Object.DestroyImmediate(go); } else { MadGameObject.SafeDestroy(go); } } protected T CreateHidden(string name, Transform parent = null) where T : Component { if (container == null) { container = new GameObject("_container").transform; container.gameObject.hideFlags = HideFlags.HideAndDontSave; } if (parent == null) { parent = container; } T val = MadTransform.CreateChild(parent, name, true); if (val is MadSprite) { MadSprite madSprite = val as MadSprite; madSprite.panel = panel; if (val.GetType() == typeof(MadSprite)) { madSprite.hasPremultipliedAlpha = premultipliedAlpha; } } MadGameObject.SetActive(val.gameObject, true); val.gameObject.hideFlags = HideFlags.HideAndDontSave; hiddenObjects.Insert(0, val.gameObject); return val; } protected override bool IsVisible() { if (!base.IsVisible()) { return false; } if (anchorObject != null) { Camera main; if (anchorCamera != null) { main = anchorCamera; } else { main = Camera.main; if (main == null) { return true; } } Vector3 lhs = anchorObject.transform.position - main.transform.position; float num = Vector3.Dot(lhs, main.transform.forward); return num >= 0f; } return true; } protected bool TextureValid(Texture2D tex, string atlasTex) { if (useAtlas) { return AtlasTextureValid(atlasTex); } return tex != null; } protected void SetTexture(MadSprite sprite, Texture2D tex, string atlasTex) { if (useAtlas) { sprite.inputType = MadSprite.InputType.TextureAtlas; sprite.textureAtlas = atlas; sprite.textureAtlasSpriteGUID = atlasTex; sprite.texture = null; } else { sprite.inputType = MadSprite.InputType.SingleTexture; sprite.textureAtlas = null; sprite.lastTextureAtlasSpriteGUID = null; sprite.texture = tex; } } protected bool AtlasTextureValid(string guid) { if (atlas == null) { return false; } MadAtlas.Item item = atlas.GetItem(guid); if (item != null) { return true; } return false; } protected static MadSprite.PivotPoint Translate(Pivot pivot) { switch (pivot) { case Pivot.Left: return MadSprite.PivotPoint.Left; case Pivot.Top: return MadSprite.PivotPoint.Top; case Pivot.Right: return MadSprite.PivotPoint.Right; case Pivot.Bottom: return MadSprite.PivotPoint.Bottom; case Pivot.TopLeft: return MadSprite.PivotPoint.TopLeft; case Pivot.TopRight: return MadSprite.PivotPoint.TopRight; case Pivot.BottomRight: return MadSprite.PivotPoint.BottomRight; case Pivot.BottomLeft: return MadSprite.PivotPoint.BottomLeft; case Pivot.Center: return MadSprite.PivotPoint.Center; default: Debug.Log("Unknown pivot point: " + pivot); return MadSprite.PivotPoint.Center; } } protected static Vector2 PivotOffset(Pivot pivot) { switch (pivot) { case Pivot.Left: return new Vector2(0f, -0.5f); case Pivot.Top: return new Vector2(-0.5f, -1f); case Pivot.Right: return new Vector2(-1f, -0.5f); case Pivot.Bottom: return new Vector2(-0.5f, 0f); case Pivot.TopLeft: return new Vector2(0f, -1f); case Pivot.TopRight: return new Vector2(-1f, -1f); case Pivot.BottomRight: return new Vector2(-1f, 0f); case Pivot.BottomLeft: return new Vector2(0f, 0f); case Pivot.Center: return new Vector2(-0.5f, -0.5f); default: Debug.Log("Unknown pivot point: " + pivot); return Vector2.zero; } } } }