feat: 增加本地化图片播放
This commit is contained in:
@@ -402,6 +402,13 @@ namespace AibisDream
|
||||
return panel.ShowObj(picName, duration);
|
||||
}
|
||||
|
||||
[YarnCommand("show_l10n_obj")]
|
||||
public static IEnumerator ShowL10nObj(string picName, float duration = 1)
|
||||
{
|
||||
var panel = UIManager.Instance.GetPanel<PlayToolPanel>();
|
||||
return panel.ShowL10nObj(picName, duration);
|
||||
}
|
||||
|
||||
[YarnCommand("hide_obj")]
|
||||
public static IEnumerator HideObj(float duration = 1)
|
||||
{
|
||||
@@ -470,6 +477,13 @@ namespace AibisDream
|
||||
return panel.ShowFullScreen(picName, duration);
|
||||
}
|
||||
|
||||
[YarnCommand("show_l10n_full_screen")]
|
||||
public static IEnumerator ShowL10nFullScreen(string picName, float duration = 1)
|
||||
{
|
||||
var panel = UIManager.Instance.GetPanel<PlayToolPanel>();
|
||||
return panel.ShowL10nFullScreen(picName, duration);
|
||||
}
|
||||
|
||||
[YarnCommand("hide_full_screen")]
|
||||
public static IEnumerator HideFullScreen(float duration = 1)
|
||||
{
|
||||
|
||||
@@ -197,8 +197,10 @@ namespace AibisDream.SaveSystem
|
||||
{
|
||||
public bool isObjVisible;
|
||||
public string objPicName;
|
||||
public bool objIsLocalized;
|
||||
public bool isFullScreenVisible;
|
||||
public string fullScreenPicName;
|
||||
public bool fullScreenIsLocalized;
|
||||
}
|
||||
|
||||
public enum ShowcaseDisplayMode
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AibisDream.Framework;
|
||||
|
||||
namespace AibisDream.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the file-name convention used by localized Obj sprites.
|
||||
/// Chinese uses the unsuffixed source asset; every other supported locale uses
|
||||
/// "{logicalName}-{localeCode}".
|
||||
/// </summary>
|
||||
internal static class LocalizedObjSpriteNaming
|
||||
{
|
||||
internal const string DefaultLocaleCode = "zh-Hans";
|
||||
|
||||
private static readonly string[] NonDefaultLocaleCodeValues =
|
||||
{
|
||||
"en",
|
||||
"ja-JP",
|
||||
"ru",
|
||||
"es",
|
||||
"pt-BR"
|
||||
};
|
||||
|
||||
internal static IReadOnlyList<string> NonDefaultLocaleCodes =>
|
||||
NonDefaultLocaleCodeValues;
|
||||
|
||||
internal static string NormalizeLogicalName(string picName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(picName)) return picName;
|
||||
return picName.EndsWith(".png", StringComparison.OrdinalIgnoreCase)
|
||||
? picName.Substring(0, picName.Length - 4)
|
||||
: picName;
|
||||
}
|
||||
|
||||
internal static string GetAssetLocaleCode(string localeCode)
|
||||
{
|
||||
return LocalizationKit.GetLocaleKind(localeCode) switch
|
||||
{
|
||||
LocaleKind.En => "en",
|
||||
LocaleKind.Ja => "ja-JP",
|
||||
LocaleKind.Ru => "ru",
|
||||
LocaleKind.Es => "es",
|
||||
LocaleKind.PtBr => "pt-BR",
|
||||
_ => DefaultLocaleCode
|
||||
};
|
||||
}
|
||||
|
||||
internal static string GetPicName(string logicalName, string localeCode)
|
||||
{
|
||||
string normalizedName = NormalizeLogicalName(logicalName);
|
||||
string assetLocaleCode = GetAssetLocaleCode(localeCode);
|
||||
return string.Equals(
|
||||
assetLocaleCode,
|
||||
DefaultLocaleCode,
|
||||
StringComparison.Ordinal)
|
||||
? normalizedName
|
||||
: $"{normalizedName}-{assetLocaleCode}";
|
||||
}
|
||||
|
||||
internal static IReadOnlyList<string> GetCandidatePicNames(
|
||||
string logicalName,
|
||||
string localeCode)
|
||||
{
|
||||
string normalizedName = NormalizeLogicalName(logicalName);
|
||||
string localizedName = GetPicName(normalizedName, localeCode);
|
||||
if (string.Equals(localizedName, normalizedName, StringComparison.Ordinal))
|
||||
return new[] { normalizedName };
|
||||
|
||||
return new[] { localizedName, normalizedName };
|
||||
}
|
||||
|
||||
internal static bool TryParseLocalizedVariant(
|
||||
string fileNameWithoutExtension,
|
||||
out string logicalName,
|
||||
out string localeCode)
|
||||
{
|
||||
foreach (string candidateCode in NonDefaultLocaleCodeValues)
|
||||
{
|
||||
string suffix = $"-{candidateCode}";
|
||||
if (!fileNameWithoutExtension.EndsWith(
|
||||
suffix,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
logicalName = fileNameWithoutExtension.Substring(
|
||||
0,
|
||||
fileNameWithoutExtension.Length - suffix.Length);
|
||||
localeCode = candidateCode;
|
||||
return true;
|
||||
}
|
||||
|
||||
logicalName = null;
|
||||
localeCode = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81844af51d08a8e40adc1a25247f2337
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using AibisDream.Framework;
|
||||
using AibisDream.Kit;
|
||||
using AibisDream.SaveSystem;
|
||||
@@ -7,6 +8,7 @@ using AibisDream.Utility;
|
||||
using DG.Tweening;
|
||||
using RainbowArt.CleanFlatUI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Localization.Settings;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.UI;
|
||||
|
||||
@@ -41,6 +43,8 @@ namespace AibisDream.UI
|
||||
private int _fullScreenOperationVersion;
|
||||
private string _currentObjPicName;
|
||||
private string _currentFullScreenPicName;
|
||||
private bool _currentObjIsLocalized;
|
||||
private bool _currentFullScreenIsLocalized;
|
||||
private bool _isObjVisible;
|
||||
private bool _isFullScreenVisible;
|
||||
|
||||
@@ -64,10 +68,7 @@ namespace AibisDream.UI
|
||||
|
||||
private static string NormalizeObjPicName(string picName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(picName)) return picName;
|
||||
return picName.EndsWith(".png", StringComparison.OrdinalIgnoreCase)
|
||||
? picName.Substring(0, picName.Length - 4)
|
||||
: picName;
|
||||
return LocalizedObjSpriteNaming.NormalizeLogicalName(picName);
|
||||
}
|
||||
|
||||
private IEnumerator LoadObjSprite(
|
||||
@@ -91,6 +92,62 @@ namespace AibisDream.UI
|
||||
completed?.Invoke(null);
|
||||
}
|
||||
|
||||
private IEnumerator LoadLocalizedObjSprite(
|
||||
string logicalName,
|
||||
Action<Sprite> completed,
|
||||
Action<string> warning = null)
|
||||
{
|
||||
yield return LocalizationKit.WaitUntilReady();
|
||||
|
||||
string localeCode = LocalizationSettings.SelectedLocale?.Identifier.Code;
|
||||
IReadOnlyList<string> candidates =
|
||||
LocalizedObjSpriteNaming.GetCandidatePicNames(logicalName, localeCode);
|
||||
|
||||
for (int index = 0; index < candidates.Count; index++)
|
||||
{
|
||||
Sprite sprite = null;
|
||||
Action<string> loadWarning = index == candidates.Count - 1
|
||||
? warning
|
||||
: null;
|
||||
yield return LoadObjSprite(
|
||||
candidates[index],
|
||||
value => sprite = value,
|
||||
loadWarning);
|
||||
if (sprite == null)
|
||||
continue;
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
string message =
|
||||
$"[PlayToolPanel] Localized sprite is missing for locale " +
|
||||
$"'{LocalizedObjSpriteNaming.GetAssetLocaleCode(localeCode)}': " +
|
||||
$"{NormalizeObjPicName(logicalName)}. Falling back to zh-Hans.";
|
||||
Debug.LogWarning(message);
|
||||
warning?.Invoke(message);
|
||||
}
|
||||
|
||||
completed?.Invoke(sprite);
|
||||
yield break;
|
||||
}
|
||||
|
||||
completed?.Invoke(null);
|
||||
}
|
||||
|
||||
private IEnumerator LoadObjSprite(
|
||||
string picName,
|
||||
bool isLocalized,
|
||||
Action<Sprite> completed,
|
||||
Action<string> warning = null)
|
||||
{
|
||||
if (isLocalized)
|
||||
{
|
||||
yield return LoadLocalizedObjSprite(picName, completed, warning);
|
||||
yield break;
|
||||
}
|
||||
|
||||
yield return LoadObjSprite(picName, completed, warning);
|
||||
}
|
||||
|
||||
private void ApplyObjSprite(Sprite sprite)
|
||||
{
|
||||
var imageAspect = (float)sprite.texture.width / sprite.texture.height;
|
||||
@@ -113,6 +170,7 @@ namespace AibisDream.UI
|
||||
_showObjImage.SetAlpha(0f);
|
||||
_showObjPanel.SetActive(false);
|
||||
_currentObjPicName = null;
|
||||
_currentObjIsLocalized = false;
|
||||
_isObjVisible = false;
|
||||
}
|
||||
|
||||
@@ -123,6 +181,7 @@ namespace AibisDream.UI
|
||||
_fullScreenImage.SetAlpha(0f);
|
||||
_fullScreenImage.gameObject.SetActive(false);
|
||||
_currentFullScreenPicName = null;
|
||||
_currentFullScreenIsLocalized = false;
|
||||
_isFullScreenVisible = false;
|
||||
}
|
||||
|
||||
@@ -131,12 +190,28 @@ namespace AibisDream.UI
|
||||
/// </summary>
|
||||
/// <returns>协程</returns>
|
||||
public IEnumerator ShowObj(string picName, float duration = 1)
|
||||
{
|
||||
yield return ShowObjInternal(picName, duration, false);
|
||||
}
|
||||
|
||||
public IEnumerator ShowL10nObj(string picName, float duration = 1)
|
||||
{
|
||||
yield return ShowObjInternal(picName, duration, true);
|
||||
}
|
||||
|
||||
private IEnumerator ShowObjInternal(
|
||||
string picName,
|
||||
float duration,
|
||||
bool isLocalized)
|
||||
{
|
||||
var version = ++_objOperationVersion;
|
||||
_showObjImage.DOKill();
|
||||
|
||||
Sprite newSprite = null;
|
||||
yield return LoadObjSprite(picName, value => newSprite = value);
|
||||
yield return LoadObjSprite(
|
||||
picName,
|
||||
isLocalized,
|
||||
value => newSprite = value);
|
||||
if (version != _objOperationVersion)
|
||||
{
|
||||
yield break;
|
||||
@@ -155,6 +230,7 @@ namespace AibisDream.UI
|
||||
if (version != _objOperationVersion) yield break;
|
||||
|
||||
_currentObjPicName = NormalizeObjPicName(picName);
|
||||
_currentObjIsLocalized = isLocalized;
|
||||
_isObjVisible = true;
|
||||
}
|
||||
|
||||
@@ -162,6 +238,7 @@ namespace AibisDream.UI
|
||||
{
|
||||
var version = ++_objOperationVersion;
|
||||
_currentObjPicName = null;
|
||||
_currentObjIsLocalized = false;
|
||||
_isObjVisible = false;
|
||||
_showObjImage.DOKill();
|
||||
yield return _showObjImage.FadeOutAsync(duration);
|
||||
@@ -170,13 +247,29 @@ namespace AibisDream.UI
|
||||
}
|
||||
|
||||
public IEnumerator ShowFullScreen(string picName, float duration = 1)
|
||||
{
|
||||
yield return ShowFullScreenInternal(picName, duration, false);
|
||||
}
|
||||
|
||||
public IEnumerator ShowL10nFullScreen(string picName, float duration = 1)
|
||||
{
|
||||
yield return ShowFullScreenInternal(picName, duration, true);
|
||||
}
|
||||
|
||||
private IEnumerator ShowFullScreenInternal(
|
||||
string picName,
|
||||
float duration,
|
||||
bool isLocalized)
|
||||
{
|
||||
var version = ++_fullScreenOperationVersion;
|
||||
_fullScreenImage.DOKill();
|
||||
_fullScreenImage.gameObject.SetActive(true);
|
||||
|
||||
Sprite newSprite = null;
|
||||
yield return LoadObjSprite(picName, value => newSprite = value);
|
||||
yield return LoadObjSprite(
|
||||
picName,
|
||||
isLocalized,
|
||||
value => newSprite = value);
|
||||
if (version != _fullScreenOperationVersion)
|
||||
{
|
||||
yield break;
|
||||
@@ -194,6 +287,7 @@ namespace AibisDream.UI
|
||||
if (version != _fullScreenOperationVersion) yield break;
|
||||
|
||||
_currentFullScreenPicName = NormalizeObjPicName(picName);
|
||||
_currentFullScreenIsLocalized = isLocalized;
|
||||
_isFullScreenVisible = true;
|
||||
}
|
||||
|
||||
@@ -201,6 +295,7 @@ namespace AibisDream.UI
|
||||
{
|
||||
var version = ++_fullScreenOperationVersion;
|
||||
_currentFullScreenPicName = null;
|
||||
_currentFullScreenIsLocalized = false;
|
||||
_isFullScreenVisible = false;
|
||||
_fullScreenImage.DOKill();
|
||||
yield return _fullScreenImage.FadeOutAsync(duration);
|
||||
@@ -214,8 +309,10 @@ namespace AibisDream.UI
|
||||
{
|
||||
isObjVisible = _isObjVisible,
|
||||
objPicName = _currentObjPicName,
|
||||
objIsLocalized = _currentObjIsLocalized,
|
||||
isFullScreenVisible = _isFullScreenVisible,
|
||||
fullScreenPicName = _currentFullScreenPicName
|
||||
fullScreenPicName = _currentFullScreenPicName,
|
||||
fullScreenIsLocalized = _currentFullScreenIsLocalized
|
||||
};
|
||||
}
|
||||
|
||||
@@ -229,13 +326,18 @@ namespace AibisDream.UI
|
||||
{
|
||||
var version = ++_objOperationVersion;
|
||||
Sprite sprite = null;
|
||||
yield return LoadObjSprite(snapshot.objPicName, value => sprite = value, warning);
|
||||
yield return LoadObjSprite(
|
||||
snapshot.objPicName,
|
||||
snapshot.objIsLocalized,
|
||||
value => sprite = value,
|
||||
warning);
|
||||
if (version == _objOperationVersion && sprite != null)
|
||||
{
|
||||
ApplyObjSprite(sprite);
|
||||
_showObjPanel.SetActive(true);
|
||||
_showObjImage.SetAlpha(1f);
|
||||
_currentObjPicName = NormalizeObjPicName(snapshot.objPicName);
|
||||
_currentObjIsLocalized = snapshot.objIsLocalized;
|
||||
_isObjVisible = true;
|
||||
}
|
||||
}
|
||||
@@ -248,13 +350,18 @@ namespace AibisDream.UI
|
||||
{
|
||||
var version = ++_fullScreenOperationVersion;
|
||||
Sprite sprite = null;
|
||||
yield return LoadObjSprite(snapshot.fullScreenPicName, value => sprite = value, warning);
|
||||
yield return LoadObjSprite(
|
||||
snapshot.fullScreenPicName,
|
||||
snapshot.fullScreenIsLocalized,
|
||||
value => sprite = value,
|
||||
warning);
|
||||
if (version == _fullScreenOperationVersion && sprite != null)
|
||||
{
|
||||
_fullScreenImage.sprite = sprite;
|
||||
_fullScreenImage.gameObject.SetActive(true);
|
||||
_fullScreenImage.SetAlpha(1f);
|
||||
_currentFullScreenPicName = NormalizeObjPicName(snapshot.fullScreenPicName);
|
||||
_currentFullScreenIsLocalized = snapshot.fullScreenIsLocalized;
|
||||
_isFullScreenVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user