Wie bearbeite ich Schlüssel-Wert-Paare (wie ein Wörterbuch) im Inspektor von Unity?


18

Ich habe ein Rechtschreibsystem, das ich erstelle. Das Prinzip ist wie folgt:

  • Jeder Spruch ist ein autonomes Fertighaus. Es enthält ein Skript mit einigen Eigenschaften (Grundschaden, Dauer ...), die im Inspektor geändert werden können.
  • Ich habe eine Spell-Enumeration, die alle möglichen Zaubersprüche im Code auflistet, der in der Spielelogik verwendet wird
  • Wenn ich einen Zauberspruch wirken möchte, muss ich in der Lage sein, die Fertighab dieses Zauberspruchs zu erhalten, um ihn zu instanziieren und seine Informationen zu lesen
  • Jeder Schauspieler (egal ob Spieler oder Feind) muss eine Liste möglicher Animationen für die Zauber haben

Die Probleme mit, wie ich versuche, umzusetzen, sind:

  • Zum Auflisten der Animationen jedes Schauspielers könnte ich ein verwenden Dictionary<Spell, Animation>, aber Wörterbücher werden vom Inspektor nicht unterstützt, was es schwierig macht, mehrere Schauspielertypen einfach zu bearbeiten.
  • Ich brauche einen Weg, um einfach auf ein Zauberspruch-Fertighaus aus der entsprechenden Enumeration zuzugreifen. Auch hier könnte ich ein Wörterbuch verwenden, aber ich kann nur im Inspektor auf Prefabs verweisen, nicht im Code, was bedeutet, dass ich dieses Wörterbuch nicht füllen kann

Ich suche nach einer Möglichkeit, meine Zaubersprüche einfach mit den entsprechenden Prefabs und Animationen zu verknüpfen


1
Darf ich vorschlagen, den Titel dieser Frage zu ändern, um auf das wörterbuchähnliche Verhalten (Zuordnen von Schlüssel-Wert-Paaren) in Unitys Inspektor Bezug zu nehmen? Dies erleichtert anderen Benutzern, die Ideen zur Lösung dieses Problems haben oder suchen, das Auffinden der Frage. Auch wenn es in diesem speziellen Fall um Zaubersprüche geht, sind dieselben Techniken allgemeiner anwendbar.
DMGregory

@DM Ich kenne Unity nicht, aber deine allgemeine Argumentation klingt vernünftig. Sei mutig und bearbeite; Rollbacks sind billig.
Anko

Antworten:


24

Eine schnelle Möglichkeit, Schlüssel-Wert-Paare in Unitys Inspector abzurufen, besteht darin, eine serialisierbare Eintragsklasse zu definieren und anschließend ein Array oder eine Liste <> davon zu verwenden. z.B...

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

   public SpellAnimationEntry[] spellAnimations;    
}

Dadurch erhalten Sie automatisch eine anpassbare Liste im Inspektor, in der Sie den Schlüssel und den Wert eingeben können, ohne einen benutzerdefinierten Inspektor schreiben zu müssen.

Das Ergebnis sieht so aus:

automatisch generierter Inspektor

(Ein Trick: Wenn die serialisierte Eingabeklasse ein Feld "Name" enthält, wird diese Zeichenfolge anstelle der langweiligen Überschriften "Element 0" angezeigt. Nützlich, wenn Sie über komplexere Daten verfügen, in denen Sie effizient navigieren möchten.)

Wenn Sie dies zu einem ScriptableObject machen, können Sie es als ein Asset behandeln, das von Entitätstypen / -instanzen gemeinsam genutzt wird, für die derselbe Animationssatz erforderlich ist. (Andere Klassen werden in Unity in der Regel pro Instanz serialisiert.) Um diesen Weg zu gehen, müssen Sie ein kleines Editor-Skript hinzufügen , mit dem Sie Instanzen davon in Ihrem Assets-Ordner erstellen können .


Bearbeiten: jetzt ist es noch einfacher - Sie können dieses Attribut einfach über Ihrem ScriptableObject hinzufügen :

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

Dadurch wird das ScriptableObject wie folgt in das Menü "Erstellen" eingefügt: Screenshot mit einem benutzerdefinierten Menü zum Erstellen in Unity


Sie können das Array optional privat und serialisiert machen, sodass es weiterhin im Inspektor angezeigt wird. Fügen Sie jedoch ein öffentliches Wörterbuch (oder ein privates Wörterbuch mit einer öffentlichen GetAnimation-Methode (Rechtschreibprüfung)) hinzu, das Clients für effizientere Suchvorgänge verwenden können. In der OnEnable () -Methode kann die SpellAnimationMap durch das von Inspektoren gefüllte Array iterieren, um dieses Wörterbuch erneut zu erstellen, und dabei den Vorteil für alle Clientinstanzen gemeinsam nutzen. (Beachten Sie, dass OnEnable () auch im Editor aufgerufen wird, wenn das Asset zum ersten Mal erstellt wird. Überprüfen Sie daher, ob Ihr Array nicht null ist, bevor Sie versuchen, es zu lesen.)

Schließlich können Sie diesem Eintragsdatentyp so viel hinzufügen, wie Sie benötigen. Dies kann zum Beispiel auch das Fertighaus oder eine beliebige Anzahl anderer Datenbits sein, die Sie mit der Rechtschreibprüfung verknüpfen möchten.

Es ist auch möglich, benutzerdefinierte Inspektoren zu schreiben, um Dictionary <,> -Felder direkt auszufüllen, aber der Eindruck, den ich bekomme, ist, dass es schwierig ist, reibungslos zu arbeiten.


Genau das, was ich getan habe, während ich auf eine Antwort gewartet habe, also werde ich diese annehmen
Malharhak,

0

Lesen Sie die Erklärung von @DMGregory

Für diejenigen, die Beispiele mögen:

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]);
        } 
    }    
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.