feat: VR手柄提示实时翻译 - 新增VRControllerTooltipLocalizer组件,语言切换时自动更新VRTK手柄tooltip文字
This commit is contained in:
parent
7c0c52ac9f
commit
33a1681f3d
@ -487,6 +487,17 @@ public class LocalizationManager : MonoBehaviour
|
||||
{ "{0}与{1}边界间距为{2}M,小于200M", new[] { "{0}与{1}边界间距为{2}M,小于200M", "Distance between {0} and {1} boundary is {2}M, less than 200M", "Distance entre {0} et {1} : {2}M, inférieure à 200M", "Расстояние между {0} и {1}: {2}м, менее 200м" } },
|
||||
{ "{0}与{1}边界间距为{2}M,小于100M", new[] { "{0}与{1}边界间距为{2}M,小于100M", "Distance between {0} and {1} boundary is {2}M, less than 100M", "Distance entre {0} et {1} : {2}M, inférieure à 100M", "Расстояние между {0} и {1}: {2}м, менее 100м" } },
|
||||
{ "{0}距离水源距离为{1}M,超出100M", new[] { "{0}距离水源距离为{1}M,超出100M", "{0} distance to water source is {1}M, exceeds 100M", "Distance de {0} à la source d'eau : {1}M, supérieure à 100M", "Расстояние от {0} до источника воды {1}м, более 100м" } },
|
||||
|
||||
// VR controller tooltips (VRTK_ControllerTooltips)
|
||||
{ "展/收", new[] { "展/收", "Deploy/Stow", "Déployer/Ranger", "Развернуть/Свернуть" } },
|
||||
{ "选中车辆", new[] { "选中车辆", "Select Vehicle", "Sélectionner le véhicule", "Выбрать машину" } },
|
||||
{ "移动", new[] { "移动", "Move", "Déplacer", "Движение" } },
|
||||
{ "射线", new[] { "射线", "Ray", "Rayon", "Луч" } },
|
||||
{ "移动车辆", new[] { "移动车辆", "Move Vehicle", "Déplacer le véhicule", "Переместить машину" } },
|
||||
{ "选择车辆", new[] { "选择车辆", "Select Vehicle", "Sélectionner le véhicule", "Выбрать машину" } },
|
||||
{ "触发物体", new[] { "触发物体", "Trigger Object", "Activer l'objet", "Активировать объект" } },
|
||||
{ "抓取物体", new[] { "抓取物体", "Grab Object", "Saisir l'objet", "Захватить объект" } },
|
||||
{ "传送", new[] { "传送", "Teleport", "Téléportation", "Телепорт" } },
|
||||
};
|
||||
|
||||
[SerializeField] private int language;
|
||||
|
||||
141
Assets/Scripts/Managers/VRControllerTooltipLocalizer.cs
Normal file
141
Assets/Scripts/Managers/VRControllerTooltipLocalizer.cs
Normal file
@ -0,0 +1,141 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VRTK;
|
||||
|
||||
/// <summary>
|
||||
/// Localizes VRTK controller tooltip text at runtime.
|
||||
/// Caches original Chinese texts from prefab fields, then updates
|
||||
/// via ResetTooltip() when the language changes.
|
||||
/// </summary>
|
||||
public class VRControllerTooltipLocalizer : MonoBehaviour
|
||||
{
|
||||
private class TooltipCache
|
||||
{
|
||||
public VRTK_ControllerTooltips component;
|
||||
public string triggerText;
|
||||
public string gripText;
|
||||
public string touchpadText;
|
||||
public string buttonOneText;
|
||||
public string buttonTwoText;
|
||||
public string startMenuText;
|
||||
}
|
||||
|
||||
private TooltipCache[] caches;
|
||||
private bool initialized;
|
||||
|
||||
void Start()
|
||||
{
|
||||
CacheTooltips();
|
||||
if (initialized) ApplyLocalization();
|
||||
LocalizationManager.LanguageChanged += OnLanguageChanged;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
LocalizationManager.LanguageChanged -= OnLanguageChanged;
|
||||
}
|
||||
|
||||
private void OnLanguageChanged()
|
||||
{
|
||||
if (initialized) ApplyLocalization();
|
||||
}
|
||||
|
||||
private void CacheTooltips()
|
||||
{
|
||||
VRTK_ControllerTooltips[] tooltips = GetComponentsInChildren<VRTK_ControllerTooltips>(true);
|
||||
if (tooltips == null || tooltips.Length == 0)
|
||||
{
|
||||
tooltips = FindObjectsOfType<VRTK_ControllerTooltips>();
|
||||
}
|
||||
|
||||
if (tooltips == null || tooltips.Length == 0) return;
|
||||
|
||||
caches = new TooltipCache[tooltips.Length];
|
||||
for (int i = 0; i < tooltips.Length; i++)
|
||||
{
|
||||
caches[i] = new TooltipCache
|
||||
{
|
||||
component = tooltips[i],
|
||||
triggerText = tooltips[i].triggerText,
|
||||
gripText = tooltips[i].gripText,
|
||||
touchpadText = tooltips[i].touchpadText,
|
||||
buttonOneText = tooltips[i].buttonOneText,
|
||||
buttonTwoText = tooltips[i].buttonTwoText,
|
||||
startMenuText = tooltips[i].startMenuText
|
||||
};
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
private void ApplyLocalization()
|
||||
{
|
||||
Font font = LocalizationManager.UIFont;
|
||||
|
||||
foreach (var cache in caches)
|
||||
{
|
||||
if (cache.component == null) continue;
|
||||
|
||||
// Set all fields with localized text, then reset once
|
||||
cache.component.triggerText = LocalizeTooltipText(cache.triggerText);
|
||||
cache.component.gripText = LocalizeTooltipText(cache.gripText);
|
||||
cache.component.touchpadText = LocalizeTooltipText(cache.touchpadText);
|
||||
cache.component.buttonOneText = LocalizeTooltipText(cache.buttonOneText);
|
||||
cache.component.buttonTwoText = LocalizeTooltipText(cache.buttonTwoText);
|
||||
cache.component.startMenuText = LocalizeTooltipText(cache.startMenuText);
|
||||
cache.component.ResetTooltip();
|
||||
|
||||
// Apply localized font to tooltip Text components after ResetTooltip
|
||||
// so SetText() has already run (it doesn't touch font, only material)
|
||||
if (font != null)
|
||||
{
|
||||
VRTK_ObjectTooltip[] objTooltips = cache.component.GetComponentsInChildren<VRTK_ObjectTooltip>(true);
|
||||
foreach (var ot in objTooltips)
|
||||
{
|
||||
ApplyFontRecursive(ot.transform, font);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyFontRecursive(Transform parent, Font font)
|
||||
{
|
||||
Text[] texts = parent.GetComponentsInChildren<Text>(true);
|
||||
foreach (var t in texts)
|
||||
{
|
||||
Color savedColor = t.color;
|
||||
t.font = font;
|
||||
t.color = savedColor;
|
||||
t.verticalOverflow = VerticalWrapMode.Overflow;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translate tooltip text that may contain \\n (literal backslash-n)
|
||||
/// or \n (actual newline) as multi-line separators.
|
||||
/// Each line is translated independently.
|
||||
/// </summary>
|
||||
private static string LocalizeTooltipText(string original)
|
||||
{
|
||||
if (string.IsNullOrEmpty(original)) return original;
|
||||
|
||||
// VRTK uses literal \\n in prefab fields; SetText() converts to \n
|
||||
if (original.Contains("\\n"))
|
||||
{
|
||||
string[] parts = original.Split(new[] { "\\n" }, System.StringSplitOptions.None);
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
parts[i] = LocalizationManager.Get(parts[i].Trim());
|
||||
return string.Join("\\n", parts);
|
||||
}
|
||||
|
||||
// Handle actual newlines (in case text was already converted)
|
||||
if (original.Contains("\n"))
|
||||
{
|
||||
string[] parts = original.Split(new[] { "\n" }, System.StringSplitOptions.None);
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
parts[i] = LocalizationManager.Get(parts[i].Trim());
|
||||
return string.Join("\n", parts);
|
||||
}
|
||||
|
||||
return LocalizationManager.Get(original);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Managers/VRControllerTooltipLocalizer.cs.meta
Normal file
11
Assets/Scripts/Managers/VRControllerTooltipLocalizer.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6e286fc5954c4045bb66e03d68ba7bb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -22,6 +22,7 @@ public class VRManager : IVRInput
|
||||
{
|
||||
SDKManager = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>(ResourcesManager.GetPath(vrtkPrefabName))).GetComponent<VRTK_SDKManager>();
|
||||
SDKManager.transform.position = postion;
|
||||
SDKManager.gameObject.AddComponent<VRControllerTooltipLocalizer>();
|
||||
SDKManager.LoadedSetupChanged += SDKManager_LoadedSetupChanged;
|
||||
VRTK_Logger.instance.throwExceptions = false;
|
||||
//leftInput = SDKManager.scriptAliasLeftController.GetComponent<IVRInput>();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user