using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// /// 图片组件类型枚举 /// public enum ImageComponentType { None = 0, Image = 1, ImageEx = 2 } /// /// 单个语言的图片排版和适配数据节点 /// [Serializable] public class ImageLanguageConfigItem { [Header("RectTransform 配置")] public Vector2 anchoredPosition = Vector2.zero; public Vector2 sizeDelta = new Vector2(100f, 100f); public Vector2 anchorMin = new Vector2(0.5f, 0.5f); public Vector2 anchorMax = new Vector2(0.5f, 0.5f); public Vector2 pivot = new Vector2(0.5f, 0.5f); public Vector3 localScale = Vector3.one; public Vector3 localRotation = Vector3.zero; [Header("Image 配置")] public bool enabled = true; public Color color = Color.white; public Image.Type type = Image.Type.Simple; public bool fillCenter = true; public Image.FillMethod fillMethod = Image.FillMethod.Horizontal; public float fillAmount = 1f; public int fillOrigin = 0; public bool preserveAspect = true; public float alphaHitTestMinimumThreshold = 0f; public bool useSpriteMesh = false; public float pixelsPerUnitMultiplier = 1f; public void ApplyToRectTransform(RectTransform rt) { if (rt == null) return; rt.anchorMin = anchorMin; rt.anchorMax = anchorMax; rt.pivot = pivot; rt.anchoredPosition = anchoredPosition; rt.sizeDelta = sizeDelta; rt.localScale = localScale; rt.localRotation = Quaternion.Euler(localRotation); } public void ReadFromRectTransform(RectTransform rt) { if (rt == null) return; anchorMin = rt.anchorMin; anchorMax = rt.anchorMax; pivot = rt.pivot; anchoredPosition = rt.anchoredPosition; sizeDelta = rt.sizeDelta; localScale = rt.localScale; localRotation = rt.localRotation.eulerAngles; } public void ApplyToImage(Image img) { if (img == null) return; img.color = color; img.type = type; img.fillCenter = fillCenter; img.fillMethod = fillMethod; img.fillAmount = fillAmount; img.fillOrigin = fillOrigin; img.preserveAspect = preserveAspect; img.alphaHitTestMinimumThreshold = alphaHitTestMinimumThreshold; img.useSpriteMesh = useSpriteMesh; img.pixelsPerUnitMultiplier = pixelsPerUnitMultiplier; } public void ReadFromImage(Image img) { if (img == null) return; color = img.color; type = img.type; fillCenter = img.fillCenter; fillMethod = img.fillMethod; fillAmount = img.fillAmount; fillOrigin = img.fillOrigin; preserveAspect = img.preserveAspect; alphaHitTestMinimumThreshold = img.alphaHitTestMinimumThreshold; useSpriteMesh = img.useSpriteMesh; pixelsPerUnitMultiplier = img.pixelsPerUnitMultiplier; } public ImageLanguageConfigItem Clone() => (ImageLanguageConfigItem)MemberwiseClone(); } /// /// 支持 Unity 序列化的字典 /// [Serializable] public class ImageLanguageConfigDictionary { public List keys = new List(); public List values = new List(); public ImageLanguageConfigItem Get(string key) { if (string.IsNullOrEmpty(key)) return null; int index = keys.IndexOf(key); return index >= 0 ? values[index] : null; } public void Set(string key, ImageLanguageConfigItem value) { int index = keys.IndexOf(key); if (index >= 0) values[index] = value; else { keys.Add(key); values.Add(value); } } public bool ContainsKey(string key) => keys.Contains(key); public void Remove(string key) { int index = keys.IndexOf(key); if (index >= 0) { keys.RemoveAt(index); values.RemoveAt(index); } } } /// /// 多语言图片排版适配器 /// [RequireComponent(typeof(RectTransform))] public class ImageLanguageAdapter : MonoBehaviour { public const string DefaultLangId = "default"; [SerializeField, Tooltip("语言配置字典")] private ImageLanguageConfigDictionary m_LanguageConfigs = new ImageLanguageConfigDictionary(); [SerializeField, Tooltip("目标图片组件类型")] private ImageComponentType m_TargetImageType = ImageComponentType.None; [SerializeField, Tooltip("关联的图片组件引用")] private Component m_TargetImageComponent; private bool m_IsApplied = false; public ImageComponentType TargetImageType { get => m_TargetImageType; set => m_TargetImageType = value; } public Component TargetImageComponent { get => m_TargetImageComponent; set => m_TargetImageComponent = value; } public ImageLanguageConfigDictionary LanguageConfigs => m_LanguageConfigs; private void Awake() => DetectTargetComponent(); private void OnEnable() { if (!Application.isPlaying || !m_IsApplied) { string langId = Application.isPlaying ? Language.Id : DefaultLangId; ApplyConfig(langId); } } #if UNITY_EDITOR private void Reset() { DetectTargetComponent(); if (!HasConfig(DefaultLangId)) ReadCurrentToConfig(DefaultLangId); } #endif public ImageLanguageConfigItem GetConfig(string languageId) => m_LanguageConfigs.Get(languageId); public void SetConfig(string languageId, ImageLanguageConfigItem config) => m_LanguageConfigs.Set(languageId, config); public void RemoveConfig(string languageId) => m_LanguageConfigs.Remove(languageId); public bool HasConfig(string languageId) => m_LanguageConfigs.ContainsKey(languageId); public List GetConfiguredLanguages() => new List(m_LanguageConfigs.keys); public void ApplyConfig(string languageId) { var config = GetConfig(languageId); if (config == null) return; config.ApplyToRectTransform(GetComponent()); if (m_TargetImageComponent != null) { m_TargetImageComponent.gameObject.SetActive(config.enabled); } if (m_TargetImageComponent is Image img) { config.ApplyToImage(img); } m_IsApplied = true; } public void ReadCurrentToConfig(string languageId) { var config = new ImageLanguageConfigItem(); config.ReadFromRectTransform(GetComponent()); if (m_TargetImageComponent is Image img) { config.ReadFromImage(img); } SetConfig(languageId, config); } public static string GetLanguageShowName(string languageId) { if (Language.languageShowDict != null && Language.languageShowDict.TryGetValue(languageId, out string showName)) return showName; return languageId; } private void DetectTargetComponent() { if (m_TargetImageComponent != null) { DetermineImageType(m_TargetImageComponent); return; } m_TargetImageComponent = GetComponent() ?? GetComponentInChildren(true) as Component ?? GetComponent() ?? GetComponentInChildren(true) as Component; DetermineImageType(m_TargetImageComponent); } private void DetermineImageType(Component component) { m_TargetImageType = component switch { ImageEx _ => ImageComponentType.ImageEx, Image _ => ImageComponentType.Image, _ => ImageComponentType.None }; } #if UNITY_EDITOR [ContextMenu("刷新组件检测")] public void Editor_ForceRefreshDetection() { DetectTargetComponent(); UnityEditor.EditorUtility.SetDirty(this); } [ContextMenu("读取当前配置")] public void Editor_ReadCurrentConfig() { ReadCurrentToConfig(DefaultLangId); UnityEditor.EditorUtility.SetDirty(this); } [ContextMenu("应用默认配置")] public void Editor_ApplyDefaultConfig() => ApplyConfig(DefaultLangId); #endif }