#if UNITY_EDITOR using Sirenix.OdinInspector; using System; using System.Linq; using TMPro; using Unity.Mathematics; using UnityEditor; using UnityEngine; namespace UguiToolkit.Editor { public class TextMeshProEntity : BaseEntity { private TextMeshProUGUI m_previewText; protected override void OnApplyTransform(Transform tf) { var rt = tf as RectTransform; var pos = ElementInfo.Position; Vector2 size = new Vector2(ElementInfo.w, ElementInfo.h); var worldPos = StageManager.Instance.PrefabContentsRoot.transform.TransformPoint(new Vector3(pos.x, pos.y, 0)); Quaternion rotation = Quaternion.identity; var oldPiovt = rt.pivot; rt.pivot = new Vector2(0.5f, 0.5f); // 调整大小 rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, size.x); rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, size.y); // 设置世界坐标 rt.position = worldPos; rt.rotation = rotation; //修正中心点 var oldRect = rt.rect; var oldLocalPosition = rt.localPosition; rt.pivot = oldPiovt; rt.localPosition = oldLocalPosition; var offsetRectPos = oldRect.position - rt.rect.position; rt.Translate(offsetRectPos); } protected override void OnApplyData(TextMeshProUGUI ui) { SetTMPByTextInfo(ui, ElementInfo); } public override void InitPreview() { if (ElementInfo == null) return; if (!TryGetComponent(out m_previewText)) { m_previewText = gameObject.AddComponent(); m_previewText.alignment = TextAlignmentOptions.Center; } OnApplyData(m_previewText); ApplyTransform(transform); } // 在保证文本坐标不变的情况下设置 对齐方式 private static void SetAlignment(TextMeshProUGUI textMeshPro, TextAlignmentOptions newAlignment) { textMeshPro.ForceMeshUpdate(); // 获取当前文本的边界框 Bounds originalBounds = textMeshPro.textBounds; // 设置新的对齐方式 textMeshPro.alignment = newAlignment; // 更新布局 textMeshPro.ForceMeshUpdate(); // 获取新的边界框 Bounds newBounds = textMeshPro.textBounds; // 计算偏移量 Vector3 offset = originalBounds.center - newBounds.center; // 调整TextMeshPro的位置 textMeshPro.transform.position += offset; } private static void SetTMPByTextInfo(TextMeshProUGUI ui, LayoutInfo.TextInfo textInfo) { // TODO: 自行扩展 // 保存当前的对齐方式 TextAlignmentOptions originalAlignment = ui.alignment; float2 sizeOffset = float2.zero; ui.alignment = TextAlignmentOptions.Center; if (!ui.hasStringID) ui.text = textInfo.text; ui.fontSize = (int)textInfo.size; ui.color = textInfo.color; if (GetTextFontPreset(textInfo, out var textFontPreset)) { ui.font = textFontPreset.tmpAsset; if (!string.IsNullOrEmpty(textFontPreset.materialPreset)) { var materialPresets = TMPro.EditorUtilities.TMP_EditorUtility.FindMaterialReferences(textFontPreset.tmpAsset); if (materialPresets != null) { var material = materialPresets.FirstOrDefault((material) => { if (material.name == textFontPreset.materialPreset) return true; return false; }); if (material) ui.fontMaterial = material; } } ui.fontStyle = textInfo.font.ToLower().Contains("bold") ? TMPro.FontStyles.Bold : TMPro.FontStyles.Normal; sizeOffset = textFontPreset.sizeOffset; } // 调整margins ui.margin = Vector4.zero; // 设置字间距 ui.characterSpacing = 0f; // 设置对齐方式 if (originalAlignment != TextAlignmentOptions.Center) SetAlignment(ui, originalAlignment); } private static bool GetTextFontPreset(LayoutInfo.TextInfo textInfo, out TextFontPresetOfUnity textFontPreset) { float CalcColorDifference(in UnityEngine.Color color1, in UnityEngine.Color color2) { return math.abs(color1.r - color2.r) * 255 + math.abs(color1.g - color2.g) * 255 + math.abs(color1.b - color2.b) * 255; } textFontPreset = null; var setting = GlobalManager.Instance.setting; if (setting != null && setting.textFontList != null) { foreach (var textFontInfoOfPsd in setting.textFontList) { if (textFontInfoOfPsd.fontNameOfPsd != null && textFontInfoOfPsd.fontNameOfPsd.Contains(textInfo.font)) { if (textFontInfoOfPsd.stroke) { if (!textInfo.IsStroke) continue; if (!textFontInfoOfPsd.allStrokeColor) { if (CalcColorDifference(textFontInfoOfPsd.strokeColor ,textInfo.strokeColor) > textFontInfoOfPsd.strokeColorThreshold) continue; } } textFontPreset = textFontInfoOfPsd; return true; } } } return false; } } } #endif