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
}