some updates
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
public class SpriteNumberDisplay : MonoBehaviour
|
||||
{
|
||||
[Header("Sprites")]
|
||||
public Sprite[] digitSprites = new Sprite[10];
|
||||
public Sprite decimalPointSprite;
|
||||
public Sprite percentSprite;
|
||||
public Sprite plusSprite;
|
||||
public Sprite minusSprite;
|
||||
|
||||
[Header("Layout")]
|
||||
public Vector2 digitSize = new Vector2(28f, 42f);
|
||||
public Vector2 decimalPointSize = new Vector2(12f, 42f);
|
||||
public Vector2 percentSize = new Vector2(28f, 42f);
|
||||
public float spacing = 2f;
|
||||
public bool centerAlign = true;
|
||||
public bool preserveAspect = true;
|
||||
public Color color = Color.white;
|
||||
[Tooltip("Canvas sorting order used by generated character sprites.")]
|
||||
public int characterSortingOrder = 0;
|
||||
|
||||
private readonly List<Image> glyphImages = new List<Image>();
|
||||
private string currentText = string.Empty;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
digitSize.x = Mathf.Max(0f, digitSize.x);
|
||||
digitSize.y = Mathf.Max(0f, digitSize.y);
|
||||
decimalPointSize.x = Mathf.Max(0f, decimalPointSize.x);
|
||||
decimalPointSize.y = Mathf.Max(0f, decimalPointSize.y);
|
||||
percentSize.x = Mathf.Max(0f, percentSize.x);
|
||||
percentSize.y = Mathf.Max(0f, percentSize.y);
|
||||
}
|
||||
|
||||
public void SetNumber(int value)
|
||||
{
|
||||
SetText(value.ToString());
|
||||
}
|
||||
|
||||
public void SetText(string value)
|
||||
{
|
||||
string next = value ?? string.Empty;
|
||||
if (currentText == next && glyphImages.Count > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
currentText = next;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
SetText(string.Empty);
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
EnsureImageCount(currentText.Length);
|
||||
|
||||
float totalWidth = CalculateTotalWidth(currentText);
|
||||
float x = centerAlign ? -totalWidth * 0.5f : 0f;
|
||||
|
||||
for (int i = 0; i < glyphImages.Count; i++)
|
||||
{
|
||||
Image image = glyphImages[i];
|
||||
if (image == null) continue;
|
||||
|
||||
if (i >= currentText.Length)
|
||||
{
|
||||
image.gameObject.SetActive(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
char c = currentText[i];
|
||||
Sprite sprite = ResolveSprite(c);
|
||||
Vector2 size = ResolveSize(c);
|
||||
|
||||
if (sprite == null)
|
||||
{
|
||||
image.gameObject.SetActive(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
RectTransform rect = image.rectTransform;
|
||||
image.gameObject.SetActive(true);
|
||||
image.sprite = sprite;
|
||||
image.color = color;
|
||||
image.preserveAspect = preserveAspect;
|
||||
ApplyCharacterSortingOrder(image);
|
||||
rect.sizeDelta = size;
|
||||
rect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
rect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||
rect.anchoredPosition = new Vector2(x + size.x * 0.5f, 0f);
|
||||
|
||||
x += size.x + spacing;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyCharacterSortingOrder(Image image)
|
||||
{
|
||||
if (image == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Canvas canvas = image.GetComponent<Canvas>();
|
||||
if (canvas == null)
|
||||
{
|
||||
canvas = image.gameObject.AddComponent<Canvas>();
|
||||
}
|
||||
|
||||
canvas.overrideSorting = true;
|
||||
canvas.sortingOrder = characterSortingOrder;
|
||||
}
|
||||
|
||||
private void EnsureImageCount(int count)
|
||||
{
|
||||
while (glyphImages.Count < count)
|
||||
{
|
||||
GameObject glyph = new GameObject("digit_" + glyphImages.Count, typeof(RectTransform), typeof(Canvas), typeof(Image));
|
||||
RectTransform rect = glyph.transform as RectTransform;
|
||||
rect.SetParent(transform, false);
|
||||
|
||||
Image image = glyph.GetComponent<Image>();
|
||||
image.raycastTarget = false;
|
||||
glyphImages.Add(image);
|
||||
}
|
||||
}
|
||||
|
||||
private float CalculateTotalWidth(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
float total = 0f;
|
||||
int visibleCount = 0;
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
if (ResolveSprite(text[i]) == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
total += ResolveSize(text[i]).x;
|
||||
visibleCount++;
|
||||
}
|
||||
|
||||
if (visibleCount > 1)
|
||||
{
|
||||
total += spacing * (visibleCount - 1);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
private Sprite ResolveSprite(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
int index = c - '0';
|
||||
return digitSprites != null && index < digitSprites.Length ? digitSprites[index] : null;
|
||||
}
|
||||
|
||||
if (c == '.') return decimalPointSprite;
|
||||
if (c == '%') return percentSprite;
|
||||
if (c == '+') return plusSprite;
|
||||
if (c == '-') return minusSprite;
|
||||
return null;
|
||||
}
|
||||
|
||||
private Vector2 ResolveSize(char c)
|
||||
{
|
||||
if (c == '.') return decimalPointSize;
|
||||
if (c == '%') return percentSize;
|
||||
return digitSize;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user