Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Text.RegularExpressions;
- using UnityEngine;
- using UnityEngine.UI;
- // Usage: icon name in text is replaced by image
- public class TextPic : Text
- {
- [System.Serializable]
- public struct IconName
- {
- public string name;
- public Sprite sprite;
- }
- /// <summary>
- /// Regular expression to replace
- /// </summary>
- static readonly Regex s_Regex =
- new Regex(@"<quad name=(.+?) size=(\d*\.?\d+%?) width=(\d*\.?\d+%?) />", RegexOptions.Singleline);
- public IconName[] inspectorIconList;
- // Scale image by x, y
- [SerializeField]
- public Vector2 imageScalingFactor = Vector2.one;
- // Offset image by x, y
- [SerializeField]
- public Vector2 imageOffset = Vector2.zero;
- // Pad image by x
- public float imagePad;
- /// <summary>
- /// Image Pool
- /// </summary>
- readonly List<Image> m_ImagesPool = new List<Image>();
- /// <summary>
- /// Vertex Index
- /// </summary>
- readonly List<int> m_ImagesVertexIndex = new List<int>();
- /// <summary>
- /// After parsing the final text
- /// </summary>
- string m_OutputText;
- Dictionary<string, Sprite> iconList = new Dictionary<string, Sprite>();
- List<Vector2> positions = new List<Vector2>();
- public override void SetVerticesDirty()
- {
- base.SetVerticesDirty();
- UpdateQuadImage();
- }
- protected override void OnPopulateMesh(VertexHelper toFill)
- {
- var orignText = m_Text;
- m_Text = m_OutputText;
- base.OnPopulateMesh(toFill);
- m_Text = orignText;
- positions.Clear();
- var vert = new UIVertex();
- for (var i = 0; i < m_ImagesVertexIndex.Count; i++)
- {
- var endIndex = m_ImagesVertexIndex[i];
- var rt = m_ImagesPool[i].rectTransform;
- var size = rt.sizeDelta;
- if (endIndex < toFill.currentVertCount)
- {
- toFill.PopulateUIVertex(ref vert, endIndex);
- var position = new Vector2((vert.position.x + size.x / 2), (vert.position.y + size.y / 2));
- position += imageOffset;
- if (i > 0)
- {
- var padVector = new Vector2(imagePad * i, 0);
- position += padVector;
- }
- positions.Add(position);
- // Erase the lower left corner of the black specks
- var end = endIndex - 3;
- toFill.PopulateUIVertex(ref vert, end);
- var pos = vert.position;
- for (int j = endIndex; j > end; j--)
- {
- toFill.PopulateUIVertex(ref vert, endIndex);
- vert.position = pos;
- toFill.SetUIVertex(vert, j);
- }
- }
- }
- if (m_ImagesVertexIndex.Count != 0)
- {
- m_ImagesVertexIndex.Clear();
- }
- }
- /**
- * Unity Inspector cant display Dictionary vars,
- * so we use this little hack to setup the iconList
- */
- new void Start()
- {
- if (inspectorIconList != null)
- {
- foreach (IconName icon in inspectorIconList)
- {
- iconList.Add(icon.name, icon.sprite);
- }
- }
- }
- void UpdateQuadImage()
- {
- #if UNITY_EDITOR
- if (UnityEditor.PrefabUtility.GetPrefabType(this) == UnityEditor.PrefabType.Prefab)
- {
- return;
- }
- #endif
- m_OutputText = GetOutputText();
- m_ImagesVertexIndex.Clear();
- foreach (Match match in s_Regex.Matches(m_OutputText))
- {
- var picIndex = match.Index;
- var endIndex = picIndex * 4 + 3;
- m_ImagesVertexIndex.Add(endIndex);
- m_ImagesPool.RemoveAll(image => image == null);
- if (m_ImagesPool.Count == 0)
- {
- GetComponentsInChildren<Image>(m_ImagesPool);
- }
- if (m_ImagesVertexIndex.Count > m_ImagesPool.Count)
- {
- var resources = new DefaultControls.Resources();
- var go = DefaultControls.CreateImage(resources);
- go.layer = gameObject.layer;
- var rt = go.transform as RectTransform;
- if (rt)
- {
- rt.SetParent(rectTransform);
- rt.localPosition = Vector3.zero;
- rt.localRotation = Quaternion.identity;
- rt.localScale = Vector3.one;
- }
- m_ImagesPool.Add(go.GetComponent<Image>());
- }
- var spriteName = match.Groups[1].Value;
- var img = m_ImagesPool[m_ImagesVertexIndex.Count - 1];
- if (img.sprite == null || img.sprite.name != spriteName)
- {
- if (inspectorIconList != null && inspectorIconList.Length > 0)
- {
- foreach (IconName icon in inspectorIconList)
- {
- if (icon.name == spriteName)
- {
- img.sprite = icon.sprite;
- break;
- }
- }
- }
- }
- img.rectTransform.sizeDelta = new Vector2(fontSize * imageScalingFactor.x, fontSize * imageScalingFactor.y);
- img.enabled = true;
- if (positions.Count == m_ImagesPool.Count)
- {
- img.rectTransform.anchoredPosition = positions[m_ImagesVertexIndex.Count - 1];
- }
- }
- for (var i = m_ImagesVertexIndex.Count; i < m_ImagesPool.Count; i++)
- {
- if (m_ImagesPool[i])
- {
- m_ImagesPool[i].enabled = false;
- }
- }
- }
- string GetOutputText()
- {
- var fixedString = this.text;
- if (inspectorIconList != null && inspectorIconList.Length > 0)
- {
- foreach (IconName icon in inspectorIconList)
- {
- if (!string.IsNullOrEmpty(icon.name))
- {
- fixedString = fixedString.Replace(icon.name, "<quad name=" + icon.name + " size=" + fontSize + " width=1 />");
- }
- }
- }
- return fixedString;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement