docs.unity3d.com
    目次を表示する/隠す

    Persistent Variables Source

    Smart String に引数を指定するためには、多くの場合はスクリプトの記述が必要になります。Persistent Variables Sourceは、Global Variable (グローバル変数) および LocalizedString Local Variable (ローカル変数) と連携して、スクリプトなしでの Smart String への引数指定を可能にします。エディター内で様々なデータ型の引数を設定し、カスタム引数を作成することができます。

    Inspector ウィンドウに表示された Smart String の Persistent Variables Source フィールド

    Local Variables

    Local Variable (ローカル変数) を使用すると、ローカライズ済み文字列に引数を設定することができます。この文字列はスクリプトで駆動できます。ローカル変数はエディターまたはスクリプトを使用して追加できます。使用中のローカル変数の値を変更すると、ローカライズ済み文字列が自動的に更新されます。

    ローカル変数は再生モードの外でプレビューできるので、Smart String が素早く作成できます。このため、ローカル変数は Smart String を様々な入力でテストするのに最適です。ローカル変数は Smart String が完了したら置き換えることができます。

    エディター内でプレビュー中のローカル変数

    {player-name} scored {score} points and {objective:Completed|Failed} the objective. という Smart String は、Player 1 scored 55 points and Completed the objective になります。

    グローバル変数

    複数の Global Variable (グローバル変数) を使用して Persistent Variables ソースを設定することで、追加的な引数を用いることなくデータを外部のソースからプルして Smart String に変換することができます。グローバル変数の値が変更された時に、現在それを使用している LocalizedStrings が自動的に更新されるように設定することも可能です。

    グローバル変数にアクセスするには、以下の構造を持つプレースホルダー内でドット表記を使用します。

    {group-name.variable-name}
    {group-name.nested-group-name.variable-name}
    

    Variables Group アセット

    Variables Group アセットは、Persistent Variable (永続変数) あるいは Nested Variable Group (ネストした変数グループ) を複数含むことができます。Variable Group の作成は Assets メニューから行えます (Assets > Create > Localization > Variables Group)。Variables Group は、Global Variables Group (Smart String からアクセス可能) として Persistent Variables ソースに割り当てることができます。また、ローカライズ済み文字列の Local Argument (ローカル引数) に割り当てることも可能です。ローカル引数は、そのローカライズ済み文字列インスタンスからのみアクセス可能です。

    Inspector ウィンドウに、5 つの変数が設定された Variables Group アセットが表示されています。(上から順に、名前が my-float で値が 1.23 の float 型変数、名前が my-string で値が "This is an example" の string 型変数、名前が int-variable で値が 1 の int 型変数、名前が my-bool でチェックボックスが有効になった bool 型変数、名前が nested-group で Nested Group というアセットへの参照を持つネストされた変数フィールド)

    Smart String から Global Variables (グローバル変数) へのアクセスを可能にするには、Smart Format Sources リストに Persistent Variables Source を追加する必要があります。

    スペースを含まない一意の名前を持つ Variable Group であれば、リストに追加できます。

    以下は、global という名前の 1 つのグループの例です。

    2 つの Inspector パネル。左側に、上記の Variables Group アセットへのグローバル変数参照で構成された永続ソースが表示されており、これが右側のパネルにも表示されています。

    Smart String の例 結果
    My Floats value is {global.my-float} My Floats value is 1.23
    {global.my-string} of using global variables. This is an example of using global variables.
    The door is {global.my-bool:Open|Closed}. The door is Open
    This is an integer {global.int-variable} as Hex {global.int-variable:X}. This is an integer 255 as Hex FF
    Values can be nested {global.nested-group.player-name} Values can be nested Player 1

    更新のトリガー

    Persistent Variable は、現在それを使用している LocalizedStrings に自動更新をトリガーできます。つまり、更新が必要な UI フィールドがどれかをトラッキングできます。値が変更されると LocalizedStrings が自動的に新しい値に更新されます。LocalizedStrings を自動的に更新するように変数を設定するには、変数に IVariableValueChanged インターフェースを実装させます。LocalizedStrings は、それがどの変数を参照するか確認し、その変数の Value Changed イベントに自身を追加します。値が変更されると、Value Changed イベントが実行されて LocalizedStrings が自動的に新しい値に更新されます。

    var source = LocalizationSettings.StringDatabase.SmartFormatter.GetSourceExtension<PersistentVariablesSource>();
    var myFloat = source["global"]["my-float"] as FloatVariable;
    
    // This will trigger an update
    myFloat.Value = 123;
    

    PersistentVariablesSource Update Scope 内で更新することで、複数の変数を変更した場合に LocalizedStrings の自動更新を停止することができます。これによって不要な更新を防ぐことができます。

    public class RandomPlayerStats : MonoBehaviour
    {
        public string[] stats = new[] { "vitality", "endurance", "strength", "dexterity", "intelligence" };
    
        public void RandomStats()
        {
            var source = LocalizationSettings.StringDatabase.SmartFormatter.GetSourceExtension<PersistentVariablesSource>();
            var nestedGroup = source["global-sample"]["player"] as NestedVariablesGroup;
    
            // An UpdateScope or using BeginUpdating and EndUpdating can be used to combine multiple changes into a single Update.
            // This prevents unnecessary string refreshes when updating multiple Global Variables.
            using (PersistentVariablesSource.UpdateScope())
            {
                foreach (var name in stats)
                {
                    var variable = nestedGroup.Value[name] as IntVariable;
                    variable.Value = Random.Range(0, 10);
                }
            }
        }
    }
    

    Persistent Variable の型

    デフォルトでは以下の Persistent Variable (永続変数) が追加可能です。

    名前 説明
    Float 単一の float 値を含みます。
    String 単一の文字列値を含みます。
    Integer 単一の整数値を含みます。
    Bool 単一のブール値を含みます。
    Object Reference UnityEngine オブジェクトを参照するために使用できます。
    Nested Variables Group Persistent Variables Group アセットへの参照を含めるために使用できます。変数のネスティングも可能です。
    LocalizedString ネストされた翻訳を提供するために使用できます。

    ネストされた翻訳

    Localized String は永続変数にすることができ、これによって翻訳のネスティングが可能になります。 例えば、以下の動的文字列では、ローカライズされた値を項目名と色の両方に使用することもできます。 The {item} is {color}.

    Localized String は以下のように設定する必要があります。

    Inspector に、2 つのローカル変数を持つ LocalizedString が表示されています。これらの 2 つの変数も LocalizedStrings であり、1 つは item という名前で、もう 1 つは color という名です。English の値は The {item} is {color} です。

    Localization Table ウィンドウに、相互にネスト可能な複数のエントリーが表示されています。

    ネストされた Localized String は書式設定の段階で抽出されます。ネストされた Localized String が現在使用不可能な場合 (テーブルがまだ読み込み中の場合など) は、空の文字列が返されます。文字列が読み込まれると ValueChanged イベントがトリガーされ、これがルート LocalizedString の更新をトリガーします。これを回避したい場合は、(ネストされたテーブルがルートテーブルと異なる場合は) ネストされたテーブルの プリロード を有効にすることをお勧めします。

    性別の処理

    一部の言語では、使用すべき単語のバージョンが性別 (gender) によって変わることがあります。例えばスペイン語では、全ての名詞に性別があり、男性か女性のどちらかです。 項目の性は文章の構造に影響を及ぼします。

    The {item} is {color} という文章は、スペイン語に翻訳されると性に基づいて変化します。

    masculine (男性) の場合、El {item} es {masculine color} という構造になります。

    feminine (女性) の場合、 La {item} es {feminine color} という構造になります。

    例えば、項目が pen (bolígrafo) (ペン) である場合は男性バージョンが使用される必要があり、色が赤 (red) であれば、それに関しても男性バージョン (rojo) を使用する必要があります。 文章は El bolígrafo es rojo となります。

    これを処理するひとつの方法は Choose フォーマッターを使用することです。

    例えば {gender:choose(Male|Female):El|La} {item} es {color} を例に挙げましょう。この例では、LocalizedString 内でローカル変数によって性を定義することができます。

    翻訳者が項目の性を定義できるようにするには、例えば以下のようにメタデータを追加します。

    [Metadata(AllowedTypes = MetadataType.StringTableEntry)]
    [Serializable]
    public class ItemGender : IMetadata
    {
        public enum Gender
        {
            None,
            Female,
            Male
        }
    
        public Gender gender = Gender.None;
    }
    

    これにより、翻訳者が Spanish Entry (スペイン語のエントリー) にメタデータを追加してそのエントリーの性別を定義できるようになります。これを Google スプレッドシート や CSV に同期させれば、翻訳者が Unity を使用せずにリモートで性別を設定できるようになります。

    スペイン語のテキスト boligrafo (pen) が表示されたスクリーンショット。テキストの隣で、Item Gender (項目の性) のメタデータが Male (男性) に設定されています。

    メタデータをアクセス可能にするには、メタデータスクリプト内に IMetadataVariable インターフェースを実装してください。

    以下は、Gender メタデータの更新方法の一例です。

    [Metadata(AllowedTypes = MetadataType.StringTableEntry)]
    [Serializable]
    public class ItemGender : IMetadata, IMetadataVariable
    {
        public enum Gender
        {
            None,
            Female,
            Male
        }
    
        public Gender gender = Gender.None;
    
        /// <summary>
        /// The name used to identify this metadata.
        /// </summary>
        public string VariableName => "gender";
    
        public object GetSourceValue(ISelectorInfo _) => gender;
    }
    

    VariableName は、どのメタデータを使用するかを特定します。その上で GetSourceValue が書式設定中にその値を抽出します。

    {item.gender} を含んだ文字列は、返されたエントリーから Gender メタデータを抽出できます。 ネストされた Localized String も現在の値にアクセスでき、これはネストされたスコープ内で使用できます。つまり、red の翻訳された文字列は以下のようになります。

    {gender:choose(Male|Female):rojo|roja}

    セレクター gender はまず現在の値でチェックされ、見付からなかった場合はローカル変数がチェックされます。つまり、完全なパスを指定する必要がなく、(gender に一致するセレクターを持つものであれば) 様々な型のデータを使用できます。

    最終的な Spanish (スペイン語) の翻訳は以下のようになります。

    {item.gender:choose(Male|Female):El|La} {item} es {item:{color}}

    ネストされた翻訳の書式設定を行う場合、それらは現在の LocalizedString 内で定義された親ローカル変数とローカル変数にアクセスすることができます。ローカル変数が最初に評価され、ローカルで一致がなければ、親変数が続いて評価されます。

    色は以下のように翻訳されます。

    色 Spanish (スペイン語)
    red {gender:choose(Male|Female):rojo|roja}
    green verde
    blue azul
    white {gender:choose(Male|Female):blanco|blanca}
    black {gender:choose(Male|Female):negro|negra}

    ノート: 性別バージョンがない色もあります。

    項目 (backpack、pen) あるいは色 (white、black、red、green、blue) を選択すると英語 (English) あるいはスペイン語 (Spanish) のテキストが生成される様子を示すアニメーション

    以下の図は、この Smart String の構造を示したものです。

    Smart String の構造と、各部がどのように評価されるかを示した図

    この図は、"The backpack is red" の Spanish (スペイン語) 翻訳がどのように解決されるかを示しています。

    Smart String の構造と、各部がどのように評価されるかを示した図

    上の例は、パッケージサンプル内の Persistent Variables サンプル下にあります。

    カスタムの永続変数

    カスタム変数は、シリアル化可能 (Serializable) で IVariable を実装している必要があります。以下の例は、変数を使用して現在の時刻を返す方法を示しています。

    /// <summary>
    /// This is an example of a Global Variable that can return the current time.
    /// </summary>
    [DisplayName("Current Date Time")]
    public class CurrentTime : IVariable
    {
        public object GetSourceValue(ISelectorInfo _) => DateTime.Now;
    }
    

    この例は、XML テキストを XElement 変数に変換するための変数の作成方法を示しています。

    [DisplayName("XML Text")]
    public class XmlElement : IVariable
    {
        public string xmlText;
    
        public object GetSourceValue(ISelectorInfo selector)
        {
            try
            {
                if (!string.IsNullOrEmpty(xmlText))
                {
                    return XElement.Parse(xmlText);
                }
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }
    
            return null;
        }
    }
    

    変数を使用する LocalizedString の更新をトリガーするには、IVariableValueChanged インターフェースを実装してください。

    [Serializable]
    public class MyVariable : IVariable, IVariableValueChanged
    {
        [SerializeField]
        string m_Value;
    
        public string Value
        {
            get => m_Value;
            set
            {
                if (m_Value == value)
                    return;
    
                m_Value = value;
                ValueChanged?.Invoke(this);
            }
        }
    
        public event Action<IVariable> ValueChanged;
    
        public object GetSourceValue(ISelectorInfo _) => Value;
    }
    

    カスタムの変数グループ

    Custom Variable Group (カスタムの変数グループ) を使用して、カスタム変数を返すことができます。以下の例はその方法を示したものです。

    struct ReturnValue : IVariable
    {
        public object SourceValue { get; set; }
    
        public object GetSourceValue(ISelectorInfo _) => SourceValue;
    }
    
    /// <summary>
    /// This example shows how a nested group can be used to return custom data without the need for Reflection.
    /// </summary>
    [DisplayName("Weapon Damage")]
    [Serializable]
    public class WeaponDamageGroup : IVariableGroup, IVariable
    {
        public object GetSourceValue(ISelectorInfo _) => this;
    
        public bool TryGetValue(string key, out IVariable value)
        {
            switch (key)
            {
                case "sword":
                    value = new ReturnValue { SourceValue = 6 };
                    return true;
    
                case "mace":
                    value = new ReturnValue { SourceValue = 5 };
                    return true;
    
                case "axe":
                    value = new ReturnValue { SourceValue = 8 };
                    return true;
    
                case "dagger":
                    value = new ReturnValue { SourceValue = 2 };
                    return true;
            }
    
            value = null;
            return false;
        }
    }
    
    概要
    • Local Variables
    • グローバル変数
      • Variables Group アセット
    • 更新のトリガー
    • Persistent Variable の型
    • ネストされた翻訳
      • 性別の処理
    • カスタムの永続変数
    • カスタムの変数グループ
    トップに戻る
    Copyright © 2023 Unity Technologies — 商標と利用規約
    • 法律関連
    • プライバシーポリシー
    • クッキー
    • 私の個人情報を販売または共有しない
    • Your Privacy Choices (Cookie Settings)