using TMPro; using UnityEngine; namespace AibisDream.Framework { [DisallowMultipleComponent] [RequireComponent(typeof(TMP_Text))] public sealed class LocalizedTypography : MonoBehaviour { [SerializeField] private TypographyRole role = TypographyRole.Body; [SerializeField] private bool applyMetrics = true; [SerializeField, HideInInspector] private bool baselineCaptured; [SerializeField, HideInInspector] private float baseFontSize; [SerializeField, HideInInspector] private float baseLineSpacing; [SerializeField, HideInInspector] private float baseCharacterSpacing; private TMP_Text target; public TypographyRole Role => role; public TMP_Text Target => target != null ? target : target = GetComponent(); private void Reset() { target = GetComponent(); CaptureBaseline(); } private void Awake() { target = GetComponent(); // Prefab variants can override TMP metrics without overriding the // baseline serialized by the source prefab. Capture the fully // resolved instance values before the first profile is applied. CaptureBaseline(); } private void OnEnable() { if (!baselineCaptured) CaptureBaseline(); TypographyService.Register(this); } private void OnDisable() { TypographyService.Unregister(this); } public void ApplyProfile(TypographyProfile profile) { TMP_Text text = Target; TypographyStyle style = profile != null ? profile.Resolve(role) : null; if (text == null || style == null || !style.IsUsable) return; if (!baselineCaptured) CaptureBaseline(); TypographyService.ApplyStyle( text, style, applyMetrics, baseFontSize, baseLineSpacing, baseCharacterSpacing); } public void CaptureBaseline() { TMP_Text text = Target; if (text == null) return; baseFontSize = text.fontSize; baseLineSpacing = text.lineSpacing; baseCharacterSpacing = text.characterSpacing; baselineCaptured = true; } #if UNITY_EDITOR public void ConfigureForEditor(TypographyRole configuredRole, bool shouldApplyMetrics = true) { role = configuredRole; applyMetrics = shouldApplyMetrics; CaptureBaseline(); UnityEditor.EditorUtility.SetDirty(this); } #endif } }