Unity UI精灵文本渲染器精灵间距无法正确对齐问题求助
Unity SpriteTextRenderer 字符间距过大问题
我正在编写Unity UI脚本SpriteTextRenderer,它通过自定义SpriteFont ScriptableObject(存储字符与对应精灵的映射)生成带Image组件的UI对象来渲染字符串。目前功能基本正常,但字符间距无法正确设置。
定位逻辑均在SetText()方法中,暂时无需关注对齐相关代码,先解决间距问题。
SpriteTextRenderer 脚本代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class SpriteTextRenderer : MonoBehaviour { [SerializeField] SpriteFont font; Dictionary<char, Sprite> characters; [SerializeField] Material material; public int pixelOverlap = 0; public bool useFontOverlap = true; [SerializeField] string currentText; public string Text { get { return currentText; } private set { currentText = value; } } GameObject[] displayText = new GameObject[0]; [SerializeField] enum alignment { TopLeft, TopCenter, TopRight, MiddleLeft, Center, MiddleRight, BottomLeft, BottomCenter, BottomRight } const alignment topAlignments = alignment.TopLeft | alignment.TopCenter | alignment.TopRight; const alignment middleAlignments = alignment.MiddleLeft | alignment.Center | alignment.MiddleRight; const alignment bottomAlignments = alignment.BottomLeft | alignment.BottomCenter | alignment.BottomRight; const alignment leftAlignments = alignment.TopLeft | alignment.MiddleLeft | alignment.BottomLeft; const alignment centerAlignments = alignment.TopCenter | alignment.Center | alignment.BottomCenter; const alignment rightAlignments = alignment.TopRight | alignment.MiddleRight | alignment.BottomRight; void Start() { characters = new Dictionary<char, Sprite>{}; FillDictionary(); SetText(currentText); } void FillDictionary() { for(int i = 0; i < font.characters.Length; i++) { characters.Add(font.characters[i].character, font.characters[i].sprite); } } public void SetText(string newText) { GameObject currentCharacter; int oldLength = displayText.Length; int newLength = newText.Length; float characterPosition = 0; int overlap = useFontOverlap ? font.pixelOverlap : pixelOverlap; if(newLength > oldLength) { GameObject[] newDisplayText = new GameObject[newLength]; displayText.CopyTo(newDisplayText, 0); displayText = newDisplayText; for(int i = oldLength; i < newLength; i++) { GameObject newCharacter = new("Character (" + newText[i] + ")", typeof(RectTransform), typeof(Image)); newCharacter.transform.SetParent(this.transform, false); newCharacter.GetComponent<RectTransform>().anchorMin = new Vector2(0, 1); newCharacter.GetComponent<RectTransform>().anchorMax = new Vector2(0, 1); displayText[i] = newCharacter; } } for(int i = 0; i < newLength; i++) { currentCharacter = displayText[i]; if(i + 1 > oldLength || currentText[i] != newText[i]) { Sprite newSprite = characters[newText[i]]; float newSpriteWidth = newSprite.rect.width; currentCharacter.GetComponent<Image>().sprite = newSprite; RectTransform rt = currentCharacter.GetComponent<RectTransform>(); rt.localPosition = new Vector2(characterPosition, 0); currentCharacter.GetComponent<Image>().SetNativeSize(); characterPosition += (newSpriteWidth - overlap) * newSprite.pixelsPerUnit; } } Text = newText; Debug.Log(currentText); } }
SpriteFont 类代码
using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = "New Sprite Font", menuName = "Sprite Font")] public class SpriteFont : ScriptableObject { public int pixelOverlap; public SpriteCharacter[] characters; } [System.Serializable] public class SpriteCharacter { public char character; public Sprite sprite; }
问题细节
overlap值用于指定每个UI精灵的像素重叠量。我使用的"Large Segment" SpriteFont将pixelOverlap设为1,脚本所在UI对象的useFontOverlap设为true,预期输入字符串"1:06.237"的显示效果为紧密排列,但实际显示间距过大。
已确认的信息:
- 通过
Debug.Log()确认overlap值设置正确 - Sprite Font中的所有精灵在Sprite Editor中的矩形已精确适配可见像素(至少X轴方向)
- 所有精灵的枢轴设为左上
- 精灵图集的Pixels per Unit为19.2
内容的提问来源于stack exchange,提问作者TT87
相关产品推荐
相关产品推荐

