using System; using System.Collections.Generic; using UnityEngine.Localization.Settings; using UnityEngine.Localization.Tables; namespace UnityEngine.Localization.Metadata { /// /// Controls how the entry should be overridden when using . /// public enum EntryOverrideType { /// /// No override will be applied. /// None, /// /// The same entry will be used but from a different table. /// Table, /// /// The same table will be used but a different entry. /// Entry, /// /// An entry from a different table will be used. /// TableAndEntry } /// /// Metadata that can be applied to or a table entry to override the entry when loading a localized value. /// /// /// When fetching a localized value, an Entry Override can be used to redirect to a different table entry, such as when running on a certain platform or in a specific region. /// The Entry Override is evaluated during . /// The table entry will first be checked for an override and then the . /// ![](../manual/images/GetEntry.dot.svg) /// See also /// /// /// This example shows how to create an override that will be applied on a chosen day of the week. /// /// public interface IEntryOverride : IMetadata { /// /// Determines if the table, entry or both should be overridden. /// /// The table to use or if it is not overriden. /// The entry to use or if it is not overriden. /// Returns the fields that should be overridden. EntryOverrideType GetOverride(out TableReference tableReference, out TableEntryReference tableEntryReference); } /// /// that can be used to redirect the localization system to a different table entry based on the current runtime platform. /// This can be applied to , or . /// [Metadata(AllowedTypes = MetadataType.AllSharedTableEntries | MetadataType.AllTableEntries, AllowMultiple = false)] [Serializable] public class PlatformOverride : IEntryOverride, ISerializationCallbackReceiver { [Serializable] class PlatformOverrideData { public RuntimePlatform platform; public EntryOverrideType entryOverrideType; public TableReference tableReference; public TableEntryReference tableEntryReference; public override string ToString() { switch (entryOverrideType) { case EntryOverrideType.Table: return $"{platform}: {tableReference}"; case EntryOverrideType.Entry: return $"{platform}: {tableEntryReference}"; case EntryOverrideType.TableAndEntry: return $"{platform}: {tableReference}/{tableEntryReference}"; } return $"{platform}: None"; } } [SerializeField] List m_PlatformOverrides = new List(); #if !UNITY_EDITOR PlatformOverrideData m_PlayerPlatformOverride; #endif /// /// Add a platform override for the current table collection. /// This will result in the table being switched but the same entry name being used. /// This is useful if you want to have specialist tables that will implement the same keys for certain entries. /// /// /// This example shows how you could set up platform overrides using a table for each platform. /// /// /// The platform to override. /// The table collection to use instead of the current one. public void AddPlatformTableOverride(RuntimePlatform platform, TableReference table) => AddPlatformOverride(platform, table, default, EntryOverrideType.Table); /// /// Add a platform override for the current entry. This will use the same table collection but a different entry in the table than the one this Metadata is attached to. /// This is useful if you want to have overrides for entries that are stored in the same table. /// /// /// This example shows how you could set up platform overrides using a single table. /// /// /// The platform to override. /// The entry to use instead of the current one. public void AddPlatformEntryOverride(RuntimePlatform platform, TableEntryReference entry) => AddPlatformOverride(platform, default, entry, EntryOverrideType.Entry); /// /// Add a platform override for the table, entry or both. /// /// The platform to override. /// The table collection to use instead of the current one. /// The entry to use instead of the current one. /// Flags to insidcate the type of override to apply, table, entry or both. public void AddPlatformOverride(RuntimePlatform platform, TableReference table, TableEntryReference entry, EntryOverrideType entryOverrideType = EntryOverrideType.TableAndEntry) { PlatformOverrideData platformOverrideData = null; for (int i = 0; i < m_PlatformOverrides.Count; ++i) { if (m_PlatformOverrides[i].platform == platform) { platformOverrideData = m_PlatformOverrides[i]; break; } } if (platformOverrideData == null) { platformOverrideData = new PlatformOverrideData { platform = platform }; m_PlatformOverrides.Add(platformOverrideData); } platformOverrideData.entryOverrideType = entryOverrideType; platformOverrideData.tableReference = table; platformOverrideData.tableEntryReference = entry; } /// /// Removes the platform override for the chosen platform. /// /// The platform to remove. /// if the platform was removed or if no override was found. public bool RemovePlatformOverride(RuntimePlatform platform) { for (int i = 0; i < m_PlatformOverrides.Count; ++i) { if (m_PlatformOverrides[i].platform == platform) { m_PlatformOverrides.RemoveAt(i); return true; } } return false; } /// /// Returns the for the platform the application is currently running on using [Application.platform](https://docs.unity3d.com/ScriptReference/Application-platform.html). /// /// The table to use or if it is not overriden. /// The entry to use or if it is not overriden. /// Returns the fields that should be overridden. public EntryOverrideType GetOverride(out TableReference tableReference, out TableEntryReference tableEntryReference) { #if UNITY_EDITOR return GetOverride(out tableReference, out tableEntryReference, LocalizationSettings.Instance.Platform); #else if (m_PlayerPlatformOverride == null) { tableReference = default; tableEntryReference = default; return EntryOverrideType.None; } else { tableReference = m_PlayerPlatformOverride.tableReference; tableEntryReference = m_PlayerPlatformOverride.tableEntryReference; return m_PlayerPlatformOverride.entryOverrideType; } #endif } /// /// Returns the for the platform. /// /// The table to use or if it is not overriden. /// The entry to use or if it is not overriden. /// The platform to return the override for. /// Returns the fields that should be overridden. public EntryOverrideType GetOverride(out TableReference tableReference, out TableEntryReference tableEntryReference, RuntimePlatform platform) { for (int i = 0; i < m_PlatformOverrides.Count; ++i) { if (m_PlatformOverrides[i].platform == platform) { var po = m_PlatformOverrides[i]; tableReference = po.tableReference; tableEntryReference = po.tableEntryReference; return po.entryOverrideType; } } tableReference = default; tableEntryReference = default; return EntryOverrideType.None; } public void OnBeforeSerialize() { } public void OnAfterDeserialize() { #if !UNITY_EDITOR for (int i = 0; i < m_PlatformOverrides.Count; ++i) { if (m_PlatformOverrides[i].platform == Application.platform) { m_PlayerPlatformOverride = m_PlatformOverrides[i]; return; } } #endif } } }