Unityのインスペクターでキーと値のペア(辞書など)を編集する方法は?


18

私が作成しているスペルシステムは、次のとおりです。

  • 各呪文は独立したプレハブです。これには、インスペクターで変更できるいくつかのプロパティ(基本ダメージ、持続時間など)を持つスクリプトが含まれています。
  • ゲームロジックで使用されるコード内のすべての可能なスペルをリストするSpell列挙型があります
  • 呪文を唱えたいとき、この呪文のプレハブを取得してインスタンス化し、その情報を読むことができる必要があります
  • 各アクター(プレイヤーであれ、敵であれ)には、呪文の可能なアニメーションのリストが必要です。

私が実装しようとしている方法の問題は次のとおりです。

  • 各アクターのアニメーションをリストするにはDictionary<Spell, Animation>、を使用できますが、辞書はインスペクターでサポートされていないため、複数のアクタータイプを簡単に編集することは困難です。
  • 対応する列挙型からスペルプレハブに簡単にアクセスする方法が必要です。ここでも辞書を使用できますが、コードではなくインスペクターでプレハブのみを参照できます。つまり、この辞書を埋めることはできません

スペル列挙型を対応するプレハブとアニメーションに簡単に関連付ける方法を探しています


1
Unityのインスペクターで辞書のような動作(キーと値のペアのマッピング)を取得することを指すように、この質問のタイトルを変更することをお勧めしますか?これは、この種の問題を解決するためのアイデアを持っている、または探している他のユーザーにとって、質問を見つけやすくするのに役立ちます。この特定のケースは呪文に関するものですが、同じ手法がより広く適用可能です。
DMGregory

@DM Unityを知りませんが、あなたの一般的な推論は理にかなっています。太字で編集してくださいロールバックは安価です。
アンコ

回答:


24

Unityのインスペクターでキーと値のペアを取得する簡単な方法の1つは、シリアライズ可能なエントリクラスを定義し、それらの配列またはList <>を使用することです。例えば...

public class SpellAnimationMap : ScriptableObject
{
   [System.Serializable]
   public class SpellAnimationEntry
   {
       public Spell spell;
       public AnimationClip animation;
   }

   public SpellAnimationEntry[] spellAnimations;    
}

これにより、カスタムインスペクターを記述する必要なく、キーと値を入力できるサイズ変更可能なリストがインスペクターに表示されます。

結果は次のようになります。

自動生成されたインスペクター

(1つの秘::直列化されたエントリクラスに「名前」フィールドが含まれている場合、「文字列0」という見出しの代わりにその文字列が表示されます。より複雑なデータを効率的にナビゲートしたい場合に便利です。)

これをScriptableObjectにすると、同じアニメーションセットを必要とするエンティティタイプ/インスタンス間で共有されるアセットとして扱うことができ、それぞれのリストを複製するオーバーヘッドを回避できます。(他のクラスはUnityでインスタンスごとにシリアル化される傾向があります)。このルートに進むには、小さなエディタースクリプトを追加して、Assetsフォルダーにこれらのインスタンスを作成できるようにする必要があります


編集:さらに簡単になりました-ScriptableObjectの上にこの属性を追加するだけです

[CreateAssetMenu(fileName = "fileName.asset", menuName = "Some Folder/Menu Label")]

これにより、次のようにScriptableObjectが[作成]メニューに追加されます。 Unityでカスタマイズされた[作成]メニューを示すスクリーンショット


オプションで、インスペクターに表示されるように配列をプライベートにしてシリアル化できますが、より効率的な検索のためにクライアントが使用するパブリック辞書(またはパブリックGetAnimation(Spellスペル)メソッドを持つプライベート辞書)を追加できます。OnEnable()メソッドで、SpellAnimationMapはインスペクターが設定された配列を反復処理してこのディクショナリを構築し、すべてのクライアントインスタンス間でメリットを共有します。(OnEnable()は、アセットが最初に作成されたときにエディターでも呼び出されることに注意してください。そのため、読み取る前に配列がnullでないことを確認してください)

最後に、このエントリデータ型に必要なだけ追加できます。たとえば、プレハブ、またはスペルキーにリンクする他の任意の数のデータを含めることもできます。

また、Dictionary <、>フィールドに直接データを入力するカスタムインスペクターを作成することも可能ですが、私が得た印象は、スムーズに作業するのは面倒だということです。


私は、答えを待っている間に行うことが起こったまさに、私はこの1つを受け入れるだろう
Malharhak

0

@DMGregoryが提供する説明を読む

例が好きな人へ:

public class SpellHandler : ScriptableObject
{
    public Spell[] keys;
    public Animation[] values;

    private Dictionary<Spell, Animation> dic;

    void Awake()
    {
        int length = keys.Length;
        this.dic= new Dictionary<Spell, Animation>(length);
        for (int i = 0; i < length; i++)
        {
            this.dic.Add(keys[i], values[i]);
        } 
    }    
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.