Merge branch 'main' of http://212.24.110.183:3000/IPSEITY/Unheimlich_POC
This commit is contained in:
@@ -1,127 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using UnityEditor;
|
|
||||||
using OctoCore.Localization;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Unheimlich.Editor
|
|
||||||
{
|
|
||||||
[CustomPropertyDrawer(typeof(OctoLocalizedTextData))]
|
|
||||||
public class LocalizedTextFieldDrawer : PropertyDrawer
|
|
||||||
{
|
|
||||||
private const float LINE_HEIGHT = 20f;
|
|
||||||
private const float SPACING = 2f;
|
|
||||||
private const float LABEL_WIDTH = 80f;
|
|
||||||
|
|
||||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
||||||
{
|
|
||||||
// Height for label + EN field + FR field
|
|
||||||
return LINE_HEIGHT * 3 + SPACING * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|
||||||
{
|
|
||||||
EditorGUI.BeginProperty(position, label, property);
|
|
||||||
|
|
||||||
OctoLocalizedTextData textData = property.objectReferenceValue as OctoLocalizedTextData;
|
|
||||||
|
|
||||||
// If null, create new OctoLocalizedTextData
|
|
||||||
if (textData == null)
|
|
||||||
{
|
|
||||||
textData = CreateLocalizedTextData(property);
|
|
||||||
property.objectReferenceValue = textData;
|
|
||||||
property.serializedObject.ApplyModifiedProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw label
|
|
||||||
Rect labelRect = new Rect(position.x, position.y, position.width, LINE_HEIGHT);
|
|
||||||
EditorGUI.LabelField(labelRect, label, EditorStyles.boldLabel);
|
|
||||||
|
|
||||||
// Draw EN field
|
|
||||||
Rect enRect = new Rect(position.x, position.y + LINE_HEIGHT + SPACING, position.width, LINE_HEIGHT);
|
|
||||||
DrawLanguageField(enRect, textData, OctoLanguages.English, "EN");
|
|
||||||
|
|
||||||
// Draw FR field
|
|
||||||
Rect frRect = new Rect(position.x, position.y + (LINE_HEIGHT + SPACING) * 2, position.width, LINE_HEIGHT);
|
|
||||||
DrawLanguageField(frRect, textData, OctoLanguages.French, "FR");
|
|
||||||
|
|
||||||
EditorGUI.EndProperty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawLanguageField(Rect position, OctoLocalizedTextData textData, OctoLanguages language, string labelText)
|
|
||||||
{
|
|
||||||
if (textData == null) return;
|
|
||||||
|
|
||||||
// Ensure dictionary is initialized
|
|
||||||
if (textData.Languages.Dictionary == null || textData.Languages.Dictionary.Count == 0)
|
|
||||||
{
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
textData.Init();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get language key
|
|
||||||
string langKey = language.ToString();
|
|
||||||
|
|
||||||
// Get current value
|
|
||||||
string currentValue = "";
|
|
||||||
if (textData.Languages.Dictionary.TryGetValue(langKey, out string value))
|
|
||||||
{
|
|
||||||
currentValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw label
|
|
||||||
Rect labelRect = new Rect(position.x, position.y, LABEL_WIDTH, position.height);
|
|
||||||
EditorGUI.LabelField(labelRect, labelText + ":");
|
|
||||||
|
|
||||||
// Draw text field
|
|
||||||
Rect fieldRect = new Rect(position.x + LABEL_WIDTH, position.y, position.width - LABEL_WIDTH, position.height);
|
|
||||||
|
|
||||||
EditorGUI.BeginChangeCheck();
|
|
||||||
string newValue = EditorGUI.TextField(fieldRect, currentValue);
|
|
||||||
|
|
||||||
if (EditorGUI.EndChangeCheck())
|
|
||||||
{
|
|
||||||
// Update via indexer (Dictionary is read-only property but supports indexer)
|
|
||||||
textData.Languages.Dictionary[langKey] = newValue;
|
|
||||||
EditorUtility.SetDirty(textData);
|
|
||||||
AssetDatabase.SaveAssets();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private OctoLocalizedTextData CreateLocalizedTextData(SerializedProperty property)
|
|
||||||
{
|
|
||||||
// Get the object being edited
|
|
||||||
Object targetObject = property.serializedObject.targetObject;
|
|
||||||
string assetPath = AssetDatabase.GetAssetPath(targetObject);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(assetPath))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
string directory = Path.GetDirectoryName(assetPath);
|
|
||||||
string fileName = Path.GetFileNameWithoutExtension(assetPath);
|
|
||||||
string propertyPath = property.propertyPath.Replace(".", "_");
|
|
||||||
|
|
||||||
// Create unique name
|
|
||||||
string textDataName = $"text_{fileName}_{propertyPath}";
|
|
||||||
string textDataPath = $"{directory}/{textDataName}.asset";
|
|
||||||
|
|
||||||
// Check if already exists
|
|
||||||
OctoLocalizedTextData existingData = AssetDatabase.LoadAssetAtPath<OctoLocalizedTextData>(textDataPath);
|
|
||||||
if (existingData != null)
|
|
||||||
return existingData;
|
|
||||||
|
|
||||||
// Create new OctoLocalizedTextData
|
|
||||||
OctoLocalizedTextData newTextData = ScriptableObject.CreateInstance<OctoLocalizedTextData>();
|
|
||||||
|
|
||||||
// Initialize via Init() method
|
|
||||||
newTextData.Init();
|
|
||||||
|
|
||||||
// Save asset
|
|
||||||
AssetDatabase.CreateAsset(newTextData, textDataPath);
|
|
||||||
AssetDatabase.SaveAssets();
|
|
||||||
AssetDatabase.Refresh();
|
|
||||||
|
|
||||||
return newTextData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 6566d44f45287f943b77aa92aaefeeb0
|
|
||||||
@@ -1,57 +1,62 @@
|
|||||||
using UnityEngine;
|
using System;
|
||||||
using OctoCore.Localization;
|
|
||||||
using OctoFramework = OctoCore.OctoCore;
|
|
||||||
using Unheimlich.UI;
|
using Unheimlich.UI;
|
||||||
|
using UnityEngine;
|
||||||
|
using OctoFramework = OctoCore.OctoCore;
|
||||||
|
using OctoCore.Localization;
|
||||||
|
|
||||||
namespace Unheimlich.Features.Dialogue
|
namespace Unheimlich.Features.Dialogue
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Bridges OctoLocalizedText and PerLetterFontShifter.
|
|
||||||
/// OctoLocalizedText writes to the source TMP, which is disabled by the shifter —
|
|
||||||
/// this component intercepts Localize() and forwards the result to SetText() instead.
|
|
||||||
/// </summary>
|
|
||||||
[RequireComponent(typeof(OctoLocalizedText))]
|
|
||||||
[RequireComponent(typeof(PerLetterFontShifter))]
|
[RequireComponent(typeof(PerLetterFontShifter))]
|
||||||
public class LocalizedSubtitle : MonoBehaviour
|
public class LocalizedSubtitle : MonoBehaviour
|
||||||
{
|
{
|
||||||
private OctoLocalizedText _localizedText;
|
[SerializeField] private OctoLocalizedTextData _data;
|
||||||
|
|
||||||
|
private OctoLocalizedText _localizedText; // A retirer
|
||||||
private PerLetterFontShifter _shifter;
|
private PerLetterFontShifter _shifter;
|
||||||
|
private Action localize;
|
||||||
|
|
||||||
private void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
_localizedText = GetComponent<OctoLocalizedText>();
|
_localizedText = GetComponent<OctoLocalizedText>(); // A retirer
|
||||||
_shifter = GetComponent<PerLetterFontShifter>();
|
_shifter = GetComponent<PerLetterFontShifter>();
|
||||||
|
|
||||||
|
if (!OctoFramework.Instance)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"OctoCore.Instance not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Localize();
|
||||||
|
OctoFramework.Instance.Localization.SubscribeOnLanguageWrittenChange(localize = Localize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Start()
|
void OnDestroy()
|
||||||
{
|
{
|
||||||
// OctoLocalizedText.Awake() has already run and called Localize() into the dead TMP.
|
if (!OctoFramework.Instance) return;
|
||||||
// Pull the resolved text back out and push it into the shifter.
|
|
||||||
Refresh();
|
|
||||||
|
|
||||||
// Re-hook on language change so the shifter stays in sync.
|
if (localize != null)
|
||||||
if (OctoFramework.Instance)
|
{
|
||||||
OctoFramework.Instance.Localization.SubscribeOnLanguageWrittenChange(Refresh);
|
OctoFramework.Instance.Localization.UnsubscribeOnLanguageWrittenChange(localize);
|
||||||
|
localize = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
private void Localize()
|
||||||
{
|
{
|
||||||
if (OctoFramework.Instance)
|
string localized = "Not localized";
|
||||||
OctoFramework.Instance.Localization.UnsubscribeOnLanguageWrittenChange(Refresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
if (_data)
|
||||||
/// Pulls the current localized string and pushes it to the shifter.
|
{
|
||||||
/// </summary>
|
localized = OctoLocalization.GetLocalizedText(_data);
|
||||||
private void Refresh()
|
}
|
||||||
{
|
else // A retirer
|
||||||
// Force OctoLocalizedText to re-resolve the string into the source TMP.
|
{ // A retirer
|
||||||
_localizedText.Localize();
|
_localizedText.Localize(); // A retirer
|
||||||
|
localized = GetComponent<TMPro.TextMeshProUGUI>().text; // A retirer
|
||||||
|
} // A retirer
|
||||||
|
|
||||||
// Read it back from the source TMP (it's disabled but the .text field is still set).
|
// Read it back from the source TMP (it's disabled but the .text field is still set).
|
||||||
string resolved = GetComponent<TMPro.TextMeshProUGUI>().text;
|
_shifter.SetText(localized);
|
||||||
|
|
||||||
_shifter.SetText(resolved);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user