Bagaimana cara mengedit pasangan nilai kunci (seperti Kamus) di inspektur Unity?

18

Saya memiliki sistem mantra yang saya buat, prinsipnya adalah sebagai berikut:

  • Setiap mantra adalah cetakan rumah yang otonom. Ini berisi skrip dengan beberapa properti (kerusakan dasar, durasi ...) yang dapat dimodifikasi di inspektur.
  • Saya punya Eja enum yang mencantumkan semua mantra yang mungkin ada dalam kode, yang digunakan dalam logika permainan
  • Ketika saya ingin membuat mantra, saya harus bisa mendapatkan cetakan ini untuk membuat instance dan membaca informasi nya
  • Setiap aktor (baik itu pemain atau musuh) perlu memiliki daftar kemungkinan animasi untuk mantra

Masalah dengan bagaimana saya mencoba menerapkannya adalah:

  • Untuk membuat daftar animasi setiap aktor, saya dapat menggunakan Dictionary<Spell, Animation>, tetapi kamus tidak didukung oleh inspektur yang membuatnya sulit untuk mengedit beberapa jenis aktor dengan mudah.
  • Saya perlu beberapa cara untuk dengan mudah mengakses prefab mantra dari enum yang sesuai. Di sini saya juga bisa menggunakan kamus tetapi saya hanya bisa merujuk ke prefab di inspektur, bukan dalam kode, yang berarti saya tidak akan dapat mengisi kamus ini

Saya mencari cara untuk dengan mudah mengaitkan enum mantra saya ke cetakan dan animasi yang sesuai

Malharhak
sumber
1
Bolehkah saya menyarankan mengubah judul pertanyaan ini untuk merujuk pada mendapatkan perilaku seperti kamus (memetakan pasangan nilai kunci) di inspektur Unity? Ini akan membantu membuat pertanyaan lebih mudah ditemukan bagi pengguna lain yang memiliki, atau sedang mencari ide untuk menyelesaikan masalah semacam ini. Meskipun kasus khusus ini adalah tentang mantra, teknik yang sama lebih dapat diterapkan secara luas.
DMGregory
@DM Saya tidak tahu Unity, tetapi alasan umum Anda terdengar masuk akal. Berani dan edit; rollback murah.
Anko

Jawaban:

24

Salah satu cara cepat untuk mendapatkan pasangan nilai kunci di inspektur Unity adalah dengan menentukan kelas entri berseri, dan kemudian menggunakan array atau Daftar <> dari mereka. misalnya...

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

   public SpellAnimationEntry[] spellAnimations;    
}

Secara otomatis, ini akan memberi Anda daftar yang bisa diubah ukurannya di inspektur tempat Anda dapat memasukkan kunci dan nilai, tanpa perlu menulis inspektur khusus.

Hasilnya terlihat seperti ini:

inspektur yang dibuat secara otomatis

(Satu trik: jika kelas entri berseri berisi bidang "Nama", string itu akan ditampilkan alih-alih judul "Elemen 0" yang lunak. Berguna jika Anda memiliki data yang lebih rumit, Anda ingin dapat menavigasi secara efisien.)

Menjadikan ini sebagai ScriptableObject memungkinkan Anda untuk memperlakukannya sebagai Aset yang dibagikan antara jenis entitas / instance yang memerlukan rangkaian animasi yang sama, sehingga menghindari duplikasi daftar untuk masing-masing entitas. (Kelas-kelas lain cenderung diserialisasi per-instance dalam Unity). Untuk menempuh rute ini, Anda harus menambahkan skrip editor kecil agar Anda dapat membuat instance ini di folder Aset Anda .


Sunting: sekarang bahkan lebih mudah - Anda bisa menambahkan atribut ini di atas ScriptableObject Anda:

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

Ini menempatkan ScriptableObject ke dalam menu Buat Anda, seperti: Cuplikan layar memperlihatkan menu Buat yang disesuaikan di Unity


Anda dapat membuat array menjadi privat dan berseri secara opsional sehingga masih muncul di inspektur, tetapi menambahkan Kamus publik (atau kamus pribadi dengan metode GetAnimation (Mantra Ejaan) publik agar klien dapat menggunakan untuk pencarian yang lebih efisien. Dalam metode OnEnable (), SpellAnimationMap dapat mengulangi melalui array yang diisi oleh inspektur untuk membuat kamus ini sekali, sekali lagi membagikan manfaat di antara semua instance klien. (Perhatikan bahwa OnEnable () juga dipanggil di editor ketika aset pertama kali dibuat, jadi pastikan untuk memeriksa bahwa array Anda tidak nol sebelum Anda mencoba membacanya)

Terakhir, Anda dapat menambahkan sebanyak mungkin ke dalam tipe data entri ini yang Anda butuhkan. Ini dapat menyertakan cetakan juga, misalnya, atau sejumlah bit data lain yang ingin Anda tautkan ke kunci ejaan.

Dimungkinkan juga untuk menulis inspektur khusus untuk mengisi bidang Kamus <,> secara langsung, tetapi kesan yang saya dapatkan adalah bahwa sangat rewel untuk bekerja dengan lancar.

DMGregory
sumber
Persis apa yang saya lakukan saat menunggu jawaban, jadi, saya akan menerima yang ini
Malharhak
0

Baca penjelasan yang diberikan oleh @DMGregory

Bagi mereka yang menyukai contoh:

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]);
        } 
    }    
}
Gayan Weerakutti
sumber