Files
aibis-dream/Assets/Scripts/MiniGame/HuoShan/Language/ExpressionParticleLanguageProfile.cs
T
2026-08-02 13:43:06 +08:00

162 lines
5.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Localization;
namespace AibisDream.MiniGame.Language
{
public enum ExpressionParticleUnitMode
{
Grapheme,
Word
}
[Serializable]
public sealed class ExpressionParticleLocaleSettings
{
[SerializeField] private string localeCode = "zh-Hans";
[SerializeField] private ExpressionParticleUnitMode unitMode =
ExpressionParticleUnitMode.Grapheme;
[SerializeField, Min(0.1f)] private float targetFontScale = 1f;
[SerializeField, Min(0.1f)] private float nonTargetFontScale = 1f;
[SerializeField, Min(0.1f)] private float floatingFontScale = 1f;
[SerializeField, Min(0f)] private float nonTargetCountScale = 1f;
[SerializeField, Min(0f)] private float wordSpacing = 0.18f;
[SerializeField, Range(0.1f, 1f)] private float minimumReadablePhraseScale = 0.65f;
public string LocaleCode => localeCode;
public ExpressionParticleUnitMode UnitMode => unitMode;
public float TargetFontScale => targetFontScale;
public float NonTargetFontScale => nonTargetFontScale;
public float FloatingFontScale => floatingFontScale;
public float NonTargetCountScale => nonTargetCountScale;
public float WordSpacing => wordSpacing;
public float MinimumReadablePhraseScale => minimumReadablePhraseScale;
public int ScaleNonTargetCount(int baseCount)
{
if (baseCount < 0)
return baseCount;
return Mathf.Max(0, Mathf.RoundToInt(baseCount * nonTargetCountScale));
}
public static ExpressionParticleLocaleSettings CreateFallback()
{
return new ExpressionParticleLocaleSettings();
}
}
[CreateAssetMenu(
fileName = "ExpressionParticleLanguageProfile",
menuName = "AIBIS/火山/表达粒子语言配置")]
public sealed class ExpressionParticleLanguageProfile : ScriptableObject
{
[SerializeField] private List<ExpressionParticleLocaleSettings> locales = new();
private readonly HashSet<string> warnedFallbackLocales =
new(StringComparer.OrdinalIgnoreCase);
public IReadOnlyList<ExpressionParticleLocaleSettings> Locales => locales;
public ExpressionParticleLocaleSettings Resolve(LocaleIdentifier locale)
{
string code = locale.Code ?? string.Empty;
ExpressionParticleLocaleSettings exact = FindExact(code);
if (exact != null)
return exact;
int separator = code.IndexOf('-');
string language = separator > 0 ? code.Substring(0, separator) : code;
ExpressionParticleLocaleSettings prefix = FindLanguage(language);
if (prefix != null)
return prefix;
if (warnedFallbackLocales.Add(code))
{
Debug.LogWarning(
$"[ExpressionParticleLanguageProfile] Locale '{code}' 未配置;" +
"回退到 Grapheme 粒子模式。");
}
return ExpressionParticleLocaleSettings.CreateFallback();
}
public List<string> GetValidationErrors()
{
var errors = new List<string>();
var codes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
if (locales == null || locales.Count == 0)
{
errors.Add("表达粒子语言配置没有 Locale 项。");
return errors;
}
foreach (ExpressionParticleLocaleSettings settings in locales)
{
if (settings == null)
{
errors.Add("表达粒子语言配置包含空项。");
continue;
}
if (string.IsNullOrWhiteSpace(settings.LocaleCode))
{
errors.Add("表达粒子语言配置包含空 Locale Code。");
continue;
}
if (!codes.Add(settings.LocaleCode))
errors.Add($"表达粒子语言配置存在重复 Locale Code{settings.LocaleCode}");
}
return errors;
}
private ExpressionParticleLocaleSettings FindExact(string code)
{
if (locales == null)
return null;
foreach (ExpressionParticleLocaleSettings settings in locales)
{
if (settings != null &&
string.Equals(
settings.LocaleCode,
code,
StringComparison.OrdinalIgnoreCase))
{
return settings;
}
}
return null;
}
private ExpressionParticleLocaleSettings FindLanguage(string language)
{
if (string.IsNullOrEmpty(language) || locales == null)
return null;
foreach (ExpressionParticleLocaleSettings settings in locales)
{
if (settings == null || string.IsNullOrWhiteSpace(settings.LocaleCode))
continue;
string configured = settings.LocaleCode;
int separator = configured.IndexOf('-');
string configuredLanguage =
separator > 0 ? configured.Substring(0, separator) : configured;
if (string.Equals(
configuredLanguage,
language,
StringComparison.OrdinalIgnoreCase))
{
return settings;
}
}
return null;
}
}
}