Meskipun Unity menghasilkan inspectorJendela Unity yang menampilkan informasi tentang Pengaturan GameObject yang dipilih saat ini, aset atau proyek, memungkinkan Anda untuk memeriksa dan mengedit nilai. More info
Lihat di Glossary default untuk MonoBehaviours dan ScriptableObjects, ada alasan yang baik untuk menulis inspektur kustom, seperti:
Membuat inspektur kustom menggunakan UI Toolkit mirip dengan menggunakan Immediate Mode GUI (IMGUI), tetapi UI Toolkit memiliki beberapa keunggulan, seperti mengikat data otomatis dan dukungan undo otomatis. Di mana IMGUI menciptakan UI untuk inspektur sepenuhnya melalui script, UI Toolkit memungkinkan Anda untuk membangun UI melalui script, secara visual di UI Builder, atau kombinasi keduanya.
Anda dapat menemukan kode sumber akhir panduan ini di bagian bawah halaman ini here.
Dalam panduan ini, Anda akan membuat inspektur kustom untuk kelas MonoBehaviour, menggunakan kedua scriptsSepotong kode yang memungkinkan Anda untuk membuat Komponen Anda sendiri, memicu peristiwa permainan, memodifikasi sifat komponen dari waktu ke waktu dan menanggapi input pengguna dengan cara apa pun yang Anda sukai. More info
Lihat di Glossary dan UXML (menggunakan UI Builder) untuk membuat UI. Inspektur kustom juga akan menampilkan property drawersFitur Unity yang memungkinkan Anda untuk menyesuaikan tampilan kontrol tertentu di jendela Inspektur dengan menggunakan atribut pada skrip Anda, atau dengan mengendalikan bagaimana kelas Serializable tertentu harus terlihat More info
Lihat di Glossary kustom.
Panduan ini adalah untuk pengembang yang akrab dengan Unity, tetapi baru ke UI Toolkit. Disarankan untuk memiliki pemahaman dasar dari Unity dan C# scripting.
Panduan ini juga merujuk pada konsep berikut:
Topics covered:
Dalam panduan ini, Anda akan melakukan hal berikut:
Untuk memulai, Anda perlu membuat kelas kustom yang dapat membuat inspektur kustom untuk, yang merupakan MonoBehaviour
atau ScriptableObject
. Panduan ini bekerja dengan skrip MonoBehaviour
yang mewakili mobil sederhana dengan properti, seperti model dan warna.
Buat file skrip baru Car.cs
di dalam Assets/Scripts dan salin kode berikut ke dalamnya.
using UnityEngine;
public class Car : MonoBehaviour
{
public string m_Make = "Toyota";
public int m_YearBuilt = 1980;
public Color m_Color = Color.black;
}
Buat GameObjectObjek mendasar dalam adegan Unity, yang dapat mewakili karakter, props, pemandangan, kamera, waypoints, dan banyak lagi. Fungsi GameObject didefinisikan oleh Komponen yang melekat padanya. More info
Lihat di Glossary baru di komponen skrip sceneAdegan berisi lingkungan dan menu permainan Anda. Pikirkan setiap file Adegan unik sebagai tingkat yang unik. Di setiap Adegan, Anda menempatkan lingkungan, hambatan, dan dekorasi, pada dasarnya merancang dan membangun permainan Anda dalam potongan-potongan. More info
Lihat di Glossary dan melampirkan komponen skrip Car
ke dalamnya.
Untuk membuat inspektur kustom untuk setiap objek serial, Anda perlu membuat kelas berkembang dari kelas dasar Editor, dan tambahkan atribut CustomEditor untuk itu. Atribut ini memungkinkan Unity tahu kelas inspektur kustom ini mewakili. Aliran kerja untuk ini di UI Toolkit identik dengan GUI (IMGUI).
Buat file Car_Inspector.cs
di dalam Assets/Scripts/Editor dan salin kode berikut ke dalamnya.
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
[CustomEditor(typeof(Car))]
public class Car_Inspector : Editor
{
}
Note |
---|
File inspektur kustom harus berada di dalam folder Editor , atau dalam definisi perakitan Editor-only. Mencoba untuk membuat build mandiri akan gagal, sebagai ruang nama UnityEditor tidak tersedia. |
Jika Anda memilih GameObject Anda dengan komponen Car
pada titik ini, Unity masih akan menampilkan inspektur default. Anda harus menimpa CreateInspectorGUI() di dalam kelas Car_Inspector
Anda untuk menggantikan inspektur default.
Fungsi CreateInspectorGUI()
membangun pohon visual untuk inspektur. Fungsi perlu mengembalikan VisualElement yang mengandung UI. Pelaksanaan CreateInspectorGUI()
di bawah ini menciptakan VisualElement baru kosong dan menambahkan label ke dalamnya.
Override fungsi CreateInspectorGUI()
di dalam skrip Car_Inspector
Anda dan salin kode di bawah ini.
public override VisualElement CreateInspectorGUI()
{
// Create a new VisualElement to be the root of our inspector UI
VisualElement myInspector = new VisualElement();
// Add a simple label
myInspector.Add(new Label("This is a custom inspector"));
// Return the finished inspector UI
return myInspector;
}
UI Toolkit memungkinkan Anda untuk menambahkan kontrol UI dalam dua cara:
Bagian ini akan menggunakan UI Builder untuk membuat file UXML yang mengandung UI, dan menggunakan kode untuk memuat dan mengulang UI dari file UXML.
Buka UI Builder melalui menu Window > UI Toolkit > UI Builder dan buat Aset Visual Tree baru menggunakan entri menu File > New di dalam UI Builder.
UI Toolkit menawarkan jenis kontrol tambahan ketika Anda menggunakannya untuk membuat jendela Editor dan inspektur kustom. Secara default, kontrol Editor-only ini tidak terlihat dalam Pembuat UI. Untuk membuat mereka tersedia, Anda perlu mengaktifkan kotak cemen.Editor Extension Authoring.
Pilih <unsaved file>*.uxml
dalam tampilan Hierarchy di UI Builder dan mengaktifkan kotak cemen.Editor Extension Authoring checkbox.
Note |
---|
Jika Anda menggunakan UI Toolkit untuk membuat jendela Editor dan inspektur kustom, Anda dapat mengaktifkan pengaturan ini secara default di Project Settings > UI Builder. |
Untuk menambahkan kontrol ke UI, pilih dari Library dan tarik ke Hierarchy di atas. Anda tidak perlu menyesuaikan posisi atau ukuran kontrol baru kecuali Anda ingin memodifikasi tata letak otomatis. Secara default, label menggunakan seluruh lebar panel yang tersedia dan tinggi menyesuaikan dengan ukuran font yang dipilih.
Tambahkan kontrol label ke pohon visual dengan menyeretnya dari Library ke Hierarchy.
Anda dapat mengubah teks di dalam label dengan memilih dan mengubah teks dalam inspektur elemen di sisi kanan editor UI Builder.
Ketika UI Builder menyimpan pohon visual, itu menyimpannya sebagai Aset Pohon Visual dalam format UXML. Anda dapat mempelajari lebih lanjut tentang ini pada UXML documentation page.
UXML di bawah menampilkan kode yang dihasilkan oleh UI Builder dari langkah-langkah sebelumnya:
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="True">
<ui:Label text="Label created in UI Builder" />
</ui:UXML>
Simpan pohon visual yang Anda buat di bawah Asset > Script > Editor sebagai Car_Inspector_UXML.uxml
, gunakan menu File di UI Builder.
Untuk menggunakan file UX yang Anda buat di dalam inspektur kustom Anda, Anda perlu memuat dan mengacaukannya di dalam fungsi CreateInspectorGUI()
dan menambahkannya ke pohon visual. Untuk melakukan ini, Anda menggunakan metode CloneTree. Anda dapat lulus setiap VisualElement
sebagai parameter untuk bertindak sebagai orang tua untuk elemen yang dibuat.
Modifikasi fungsi CreateInspectorGUI()
untuk clone pohon visual di dalam file UXML dan menggunakannya dalam inspektur kustom Anda.
public override VisualElement CreateInspectorGUI()
{
// Create a new VisualElement to be the root of our inspector UI
VisualElement myInspector = new VisualElement();
// Add a simple label
myInspector.Add(new Label("This is a custom inspector"));
// Load and clone a visual tree from UXML
VisualTreeAsset visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Scripts/Editor/Car_Inspector_UXML.uxml");
visualTree.CloneTree(myInspector);
// Return the finished inspector UI
return myInspector;
}
Inspektur untuk komponen car
sekarang menampilkan dua label yang dibuat: satu melalui script, dan satu melalui UI Builder / UXML.
Kode harus memuat file Visual Tree Asset (UXML) untuk mengacaukan pohon visual, dan menggunakan jalur yang dikodekan keras dan nama file. Namun, file yang sulit dikodekan tidak dianjurkan, karena jika sifat file berubah, seperti path atau nama file, itu mungkin membatalkan kode.
Solusi yang lebih baik untuk mengakses Aset Pohon Visual adalah untuk menggunakan referensi ke file aset. GUID di dalam file meta menyimpan referensi file. Jika Anda mengubah nama atau memindahkan file, GUID tetap tidak berubah, dan Unity masih akan dapat menemukan dan memuat file dari lokasi baru.
Untuk PrefabsJenis aset yang memungkinkan Anda untuk menyimpan GameObject lengkap dengan komponen dan properti. Prefab bertindak sebagai template dari mana Anda dapat membuat instance objek baru di tempat kejadian. More info
Lihat di Glossary dan ScriptableObjects, Anda dapat menetapkan referensi ke file lain di Editor. Untuk file skrip, Unity memungkinkan pengaturan Default Reference
. Jika Anda menyatakan bidang publik tipe VisualTreeAsset
di kelas jendela, Inspektur menawarkan kemampuan untuk menyeret referensi ke bidang objek yang sesuai. Ini berarti bahwa setiap contoh baru kelas Car_Inspector
yang diisi dengan referensi yang ditetapkan ke objek VisualTreeAsset
yang sesuai. Ini adalah cara yang disarankan untuk menetapkan file UXML untuk memeriksa kustom dan skrip jendela Editor.
Buat variabel publik untuk VisualTreeAsset
di script Anda, dan menetapkan file Car_Inspector_UXML.uxml
sebagai referensi default di Editor.
public VisualTreeAsset m_InspectorXML;
Note |
---|
Referensi default hanya bekerja di Editor. Mereka tidak bekerja dengan komponen runtime dalam membangun mandiri menggunakan metode AddComponent(). |
Dengan set referensi default, Anda tidak perlu lagi memuat VisualTreeAsset
menggunakan fungsi LoadAssetAtPath
. Sebaliknya, Anda dapat menggunakan CloneTree langsung pada referensi ke file UXML Anda.
Ini mengurangi kode dalam metode CreateInspectorGUI()
ke 3 baris.
public VisualTreeAsset m_InspectorXML;
public override VisualElement CreateInspectorGUI()
{
// Create a new VisualElement to be the root of our inspector UI
VisualElement myInspector = new VisualElement();
// Load from default reference
m_InspectorXML.CloneTree(myInspector);
// Return the finished inspector UI
return myInspector;
}
Tujuan dari inspektur kustom ini adalah untuk menampilkan semua sifat kelas Car
. Ketika pengguna memodifikasi kontrol UI, nilai-nilai dalam kasus kelas Car
juga harus berubah. Untuk melakukannya, Anda perlu menambahkan kontrol UI ke pohon visual dan menghubungkannya ke properti individu kelas.
UI Toolkit mendukung menghubungkan kontrol UI ke properti serialisasi dengan data binding. Kontrol yang terikat dengan properti serialisasi secara otomatis menampilkan nilai saat ini properti, dan mereka juga secara otomatis memperbarui nilai properti jika pengguna mengubahnya di UI. Anda tidak perlu menulis kode yang mengambil nilai dari kontrol dan menulis kembali ke properti, seperti Anda akan di IMGUI.
Tambahkan kontrol TextField
untuk properti m_Make
mobil ke inspektur menggunakan UI Builder.
Untuk mengikat kontrol ke properti serial, menetapkan properti ke bidang binding-path
dari kontrol. Anda dapat melakukan ini dalam kode, UXML atau UI Builder. Properti cocok dengan nama, jadi pastikan untuk memeriksa ejaan Anda.
Bind TextField
baru untuk properti m_Make
di UI Builder.
Di bawah ini adalah kode UX untuk UI inspektur, termasuk atribut pengikat data.
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="True">
<ui:TextField label="Make of the car" text="<not set>" binding-path="m_Make" />
</ui:UXML>
Ketika Anda mengatur jalur mengikat dari kontrol, Anda memberi tahu kontrol nama properti serial harus terhubung ke. Tapi kontrol masih perlu menerima dan kasus objek serialisasi yang milik properti. Anda dapat menggunakan metode Login Login untuk mengikat objek serialisasi seperti MonoBehaviour
ke seluruh Pohon Visual, dan kontrol individu akan mengikat sifat yang tepat pada objek tersebut.
Ketika menulis inspektur kustom, mengikat otomatis. CreateInspectorGUI()
adalah mengikat implicit setelah Anda mengembalikan pohon visual Anda. Untuk mempelajari lebih lanjut, lihat halaman dokumentasi pada Data binding.
Karena UI Toolkit bekerja dengan properti serial, tidak ada kode tambahan yang diperlukan untuk mendukung fungsi Undo/Redo. Ini didukung secara otomatis.
Untuk menampilkan sifat kelas Car
, Anda harus menambahkan kontrol untuk setiap bidang. Kontrol harus sesuai dengan jenis properti sehingga dapat terikat. Sebagai contoh, int
harus terikat pada bidang Integer atau penggeser.
Alih-alih menambahkan kontrol spesifik berdasarkan jenis properti, Anda juga dapat menggunakan kontrol generik PropertyField. Kontrol ini bekerja untuk sebagian besar jenis properti serial, dan menghasilkan UI inspektur default untuk jenis properti ini.
Tambahkan kontrol PropertyField
untuk sifat m_YearBuilt
dan m_Color
kelas Car
. Menetapkan jalur mengikat untuk setiap dan mengisi teks Label
.
Keuntungan dari PropertyField
adalah UI inspektur akan secara otomatis menyesuaikan ketika Anda mengubah jenis variabel di dalam skrip Anda. Namun, Anda tidak bisa mendapatkan pratinjau kontrol di dalam UI Builder, karena jenis kontrol yang diperlukan tidak diketahui sampai pohon visual terikat dengan objek serial, dan UI Toolkit dapat menentukan jenis properti.
Sebuah laci properti kustom adalah UI inspektur kustom untuk kelas serializable kustom. Jika kelas serializable adalah bagian dari objek serialisasi lain, UI kustom menampilkan properti dalam inspektur. Dalam UI Toolkit, kontrol PropertyField
menampilkan laci properti kustom untuk lapangan jika satu ada.
Buat skrip baru Tire.cs
dalam Assets/Scripts dan salin kode berikut ke file:
[System.Serializable]
public class Tire
{
public float m_AirPressure = 21.5f;
public int m_ProfileDepth = 4;
}
Tambahkan daftar Tire
ke kelas Car
seperti yang ditunjukkan dalam kode di bawah ini:
public class Car : MonoBehaviour
{
public string m_Make = "Toyota";
public int m_YearBuilt = 1980;
public Color m_Color = Color.black;
// This car has four tires
public Tire[] m_Tires = new Tire[4];
}
Kontrol PropertyField
bekerja dengan semua jenis properti standar, tetapi juga mendukung kelas dan array serializable kustom. Untuk menampilkan sifat ban mobil, tambahkan PropertyField
lain di UI Builder dan mengikatnya ke m_Tires
.
Tambahkan kontrol PropertyField
untuk properti m_Tires
.
Anda dapat menemukan kode UXML dari Car_Inspector_UXML.uxml
yang dihasilkan untuk UI inspektur saat ini di bawah ini:
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="True">
<ui:TextField label="Make of the car" text="<not set>" binding-path="m_Make" />
<uie:PropertyField label="Year Built" binding-path="m_YearBuilt" />
<uie:PropertyField binding-path="m_Color" label="Paint Color" />
<uie:PropertyField binding-path="m_Tires" label="Tires" />
</ui:UXML>
Penggambar properti kustom memungkinkan Anda untuk menyesuaikan tampilan elemen Tire
individu dalam daftar. Dari kelas dasar Editor
, laci properti kustom berasal dari kelas PropertyDrawer. Untuk membuat UI untuk properti kustom, Anda perlu menimpa metode CreatePropertyGUI.
Buat skrip baru Tire_PropertyDrawer.cs
di dalam folder Assets/Scripts/Editor dan salin kode di bawahnya.
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
[CustomPropertyDrawer(typeof(Tire))]
public class Tire_PropertyDrawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
// Create a new VisualElement to be the root the property UI
var container = new VisualElement();
// Create drawer UI using C#
// ...
// Return the finished UI
return container;
}
}
Anda dapat menggunakan kode dan UXML untuk membuat UI untuk properti, seperti dalam inspektur yang disesuaikan. Contoh ini menggunakan kode untuk membuat UI kustom.
Buat UI kustom untuk laci properti kelas Tire
dengan memperluas metode CreatePropertyGUI
seperti yang ditunjukkan di bawah ini.
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
// Create a new VisualElement to be the root the property UI
var container = new VisualElement();
// Create drawer UI using C#
var popup = new UnityEngine.UIElements.PopupWindow();
popup.text = "Tire Details";
popup.Add(new PropertyField(property.FindPropertyRelative("m_AirPressure"), "Air Pressure (psi)"));
popup.Add(new PropertyField(property.FindPropertyRelative("m_ProfileDepth"), "Profile Depth (mm)"));
container.Add(popup);
// Return the finished UI
return container;
}
Untuk informasi lebih lanjut tentang laci properti, silakan lihat dokumentasi PropertyDrawer
Selama pengembangan inspektur kustom itu membantu untuk menjaga akses ke inspektur default. Dengan UI Toolkit, sederhana untuk menambahkan UI inspektur default ke UI kustom Anda.
Tambahkan kontrol Foldout
ke UI Anda di UI Builder, nama Default_Inspector dan menetapkan teks label:
Anda akan menggunakan UI Builder untuk membuat lipatan, tetapi bukan inspektur. Konten inspektur default menghasilkan dalam skrip inspektur dan melampirkan kontrol lipat melalui kode.
Untuk melampirkan UI inspektur default ke lipatan yang Anda buat di UI Builder, Anda harus mendapatkan referensi untuk itu. Anda dapat mengambil elemen visual lipatan dari pohon visual dari inspektur Anda. Ini dilakukan menggunakan keluarga UQuery API. Anda dapat mengambil elemen individu di dalam UI Anda dengan nama, kelas AS atau dengan jenis, atau kombinasi atribut ini.
Dapatkan referensi untuk kontrol Foldout
di dalam metode CreateInspectorGUI
Anda, menggunakan nama yang Anda set di UI Builder.
// Get a reference to the default inspector foldout control
VisualElement inspectorFoldout = myInspector.Q("Default_Inspector");
Metode FillDefaultInspector dari InspectorElement menciptakan pohon visual dengan inspektur default untuk objek serial dan melampirkannya ke elemen visual induk yang dilewatkan ke metode sebagai parameter.
Buat dan melampirkan inspektur default ke lipatan menggunakan kode di bawah ini:
// Attach a default inspector to the foldout
InspectorElement.FillDefaultInspector(inspectorFoldout, serializedObject, this);
Di bawah ini Anda dapat menemukan kode sumber penuh untuk semua file yang dibuat dalam panduan ini.
using UnityEngine;
public class Car : MonoBehaviour
{
public string m_Make = "Toyota";
public int m_YearBuilt = 1980;
public Color m_Color = Color.black;
// This car has four tires
public Tire[] m_Tires = new Tire[4];
}
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
[CustomEditor(typeof(Car))]
public class Car_Inspector : Editor
{
public VisualTreeAsset m_InspectorXML;
public override VisualElement CreateInspectorGUI()
{
// Create a new VisualElement to be the root of our inspector UI
VisualElement myInspector = new VisualElement();
// Load from default reference
m_InspectorXML.CloneTree(myInspector);
// Get a reference to the default inspector foldout control
VisualElement inspectorFoldout = myInspector.Q("Default_Inspector");
// Attach a default inspector to the foldout
InspectorElement.FillDefaultInspector(inspectorFoldout, serializedObject, this);
// Return the finished inspector UI
return myInspector;
}
}
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="True">
<ui:TextField label="Make of the car" text="<not set>" binding-path="m_Make" />
<uie:PropertyField label="Year Built" binding-path="m_YearBuilt" />
<uie:PropertyField binding-path="m_Color" label="Paint Color" />
<uie:PropertyField binding-path="m_Tires" label="Tires" />
<ui:Foldout text="Default Inspector" name="Default_Inspector" />
</ui:UXML>
[System.Serializable]
public class Tire
{
public float m_AirPressure = 21.5f;
public int m_ProfileDepth = 4;
}
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
[CustomPropertyDrawer(typeof(Tire))]
public class Tire_PropertyDrawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
// Create a new VisualElement to be the root the property UI
var container = new VisualElement();
// Create drawer UI using C#
var popup = new UnityEngine.UIElements.PopupWindow();
popup.text = "Tire Details";
popup.Add(new PropertyField(property.FindPropertyRelative("m_AirPressure"), "Air Pressure (psi)"));
popup.Add(new PropertyField(property.FindPropertyRelative("m_ProfileDepth"), "Profile Depth (mm)"));
container.Add(popup);
// Return the finished UI
return container;
}
}