using System; using UnityEngine.Localization.Settings; using UnityEngine.Localization.Tables; namespace UnityEngine.Localization { /// /// Provides a way to reference a table entry inside of a specific . /// [Serializable] public abstract partial class LocalizedReference : ISerializationCallbackReceiver { [SerializeField] TableReference m_TableReference; [SerializeField] TableEntryReference m_TableEntryReference; [SerializeField] FallbackBehavior m_FallbackState = FallbackBehavior.UseProjectSettings; [SerializeField] bool m_WaitForCompletion = false; internal Locale m_LocaleOverride; #if UNITY_EDITOR // This is so we can detect when a change is made via the inspector. protected TableReference m_CurrentTable; protected TableEntryReference m_CurrentTableEntry; #endif /// /// Provides a reference to the . /// A table reference can be either the of the table or the . /// /// /// Note: Changing this value triggers an update to any subscribers. /// See if you wish to change both the table and entry. /// /// /// This example shows the 2 ways a reference can be set. /// /// public TableReference TableReference { get => m_TableReference; set { if (value.Equals(m_TableReference)) return; m_TableReference = value; ForceUpdate(); } } /// /// Provides a reference to the entry inside of the table. /// The entry reference can be the or . /// /// Note: Changing this value triggers an update to any subscribers. /// See if you wish to change both the table and entry. /// /// This example shows the 2 ways a reference can be set. /// /// public TableEntryReference TableEntryReference { get => m_TableEntryReference; set { if (value.Equals(m_TableEntryReference)) return; m_TableEntryReference = value; ForceUpdate(); } } /// /// Can be used to override the default fallback state. /// public FallbackBehavior FallbackState { get => m_FallbackState; set => m_FallbackState = value; } /// /// Provide a locale that can be used instead of . /// A value will revert to using . /// /// /// This example shows how the can be used in order to provide an alternative to . /// /// public Locale LocaleOverride { get => m_LocaleOverride; set { if (m_LocaleOverride == value) return; m_LocaleOverride = value; ForceUpdate(); } } /// /// Determines if [WaitForCompletion](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.WaitForCompletion) should be used to force loading to be completed immediately. /// See [Synchronous Workflow](https://docs.unity3d.com/Packages/com.unity.addressables@latest?subfolder=/manual/SynchronousAddressables.html) for further details. /// Please note that [WaitForCompletion](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.WaitForCompletion) is not supported on /// [WebGL](https://docs.unity3d.com/Packages/com.unity.addressables@latest/index.html?subfolder=/manual/SynchronousAddressables.html#webgl). /// public virtual bool WaitForCompletion { get => m_WaitForCompletion; set => m_WaitForCompletion = value; } internal abstract bool ForceSynchronous { get; } /// /// Checks whether both and contain valid references, and returns true if one of them is empty. /// public bool IsEmpty => TableReference.ReferenceType == TableReference.Type.Empty || TableEntryReference.ReferenceType == TableEntryReference.Type.Empty; /// /// Sets both the and and triggers an update if there are any change subscribers. /// /// Reference to the or . /// Reference to the or . /// /// This example shows the different ways SetReference can be called. /// /// public void SetReference(TableReference table, TableEntryReference entry) { bool update = false; if (!m_TableReference.Equals(table)) { m_TableReference = table; update = true; } if (!m_TableEntryReference.Equals(entry)) { m_TableEntryReference = entry; update = true; } if (update) { ForceUpdate(); } } /// /// Returns a string representation including the and /// public override string ToString() => $"{TableReference}/{TableEntryReference.ToString(TableReference)}"; protected internal abstract void ForceUpdate(); /// /// Called when values are changed due to a change made via serialization, such as via the inspector. /// protected abstract void Reset(); public virtual void OnBeforeSerialize() { #if UNITY_EDITOR UpdateIfChangedThroughSerialization(); #endif } public virtual void OnAfterDeserialize() { #if UNITY_EDITOR UpdateIfChangedThroughSerialization(); #endif } #if UNITY_EDITOR void ChangedThroughSerialization() { Reset(); ForceUpdate(); } void UpdateIfChangedThroughSerialization() { if (!m_CurrentTable.Equals(TableReference) || !m_CurrentTableEntry.Equals(TableEntryReference)) { m_CurrentTable = TableReference; m_CurrentTableEntry = TableEntryReference; // We must defer as we can not call certain parts of Unity during serialization UnityEditor.EditorApplication.delayCall += ChangedThroughSerialization; } } #endif } }