Jendela Editor kustom memungkinkan Anda untuk memperluas Unity dengan menerapkan editor dan alur kerja Anda sendiri. Panduan ini mencakup membuat jendela Editor melalui kode, bereaksi terhadap input pengguna, membuat UI(User Interface) Memungkinkan pengguna untuk berinteraksi dengan aplikasi Anda. Unity saat ini mendukung tiga sistem UI. More info
Lihat di Glossary dapat diubah dan menangani pemuatan panas.
Dalam tutorial ini, Anda akan membuat browser spriteObjek grafis 2D. Jika Anda digunakan untuk bekerja di 3D, Sprites pada dasarnya hanya tekstur standar tetapi ada teknik khusus untuk menggabungkan dan mengelola tekstur sprite untuk efisiensi dan kenyamanan selama perkembangan. More info
Lihat di Glossary, yang menemukan dan menampilkan semua kecambah dalam proyek, dan menunjukkan mereka sebagai daftar. Memilih sprite dalam daftar akan menampilkan gambar di sisi kanan jendela.
Anda dapat menemukan contoh lengkap di bagian skrip jendela editor.
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:
Controls used in this guide:
Dalam panduan ini, Anda akan melakukan hal berikut:
Tip |
---|
Anda dapat menghasilkan kode yang diperlukan untuk membuat skrip jendela Editor di Editor Unity. Dari jendela Proyek, klik kanan dan pilih Create > UI Toolkit > Editor Window. Untuk panduan ini silakan menonaktifkan kotak centang UXML dan USS. Anda mungkin juga harus menambahkan petunjuk using tambahan di bagian atas file, seperti yang ditunjukkan di bawah ini. |
Anda dapat membuat jendela Editor melalui C# 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 dalam proyek Anda. Jendela editor kustom adalah kelas yang berasal dari kelas EditorWindow
.
Buat file skrip baru MyCustomEditor.cs
di bawah folder Assets/Editor. Tempel kode berikut ke script:
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class MyCustomEditor : EditorWindow
{
}
Note |
---|
Ini adalah jendela Editor-only yang mencakup ruang nama UnityEditor , sehingga file harus ditempatkan di bawah Editor , atau di dalam Definisi Perakitan Editor-only. |
Untuk membuka jendela Editor baru, Anda harus membuat entri di menu Editor.
Tambahkan atribut MenuItem
ke metode statis. Dalam contoh ini, nama metode statis adalah ShowMyEditor()
.
Di dalam ShowMyEditor()
, sebut metode EditorWindow.GetWindow() untuk membuat dan menampilkan jendela. Ini mengembalikan objek EditorWindow. Untuk mengatur judul jendela, mengubah properti WordPress.org.
Tambahkan fungsi berikut di dalam kelas MyCustomEditor
yang dibuat pada langkah sebelumnya.
[MenuItem("Tools/My Custom Editor")]
public static void ShowMyEditor()
{
// This method is called when the user selects the menu item in the Editor
EditorWindow wnd = GetWindow<MyCustomEditor>();
wnd.titleContent = new GUIContent("My Custom Editor");
}
Uji jendela baru Anda dengan membukanya melalui menu Unity Editor Tools > My Custom Editor.
UI Toolkit menggunakan metode CreateGUI untuk menambahkan kontrol ke Editor UI, dan Unity memanggil metode CreateGUI
secara otomatis ketika jendela perlu ditampilkan. Metode ini bekerja sama seperti metode seperti Awake
atau Update
.
Anda dapat menambahkan kontrol UI ke UI dengan menambahkan elemen visual ke pohon visual. Metode Login Login digunakan untuk menambahkan anak ke elemen visual yang ada. pohon visual dari jendela Editor diakses melalui properti rootvisualElement
.
Untuk memulai, tambahkan fungsi CreateGUI()
ke kelas editor kustom Anda dan tambahkan label 'Hello':
public void CreateGUI()
{
rootVisualElement.Add(new Label("Hello"));
}
Note |
---|
Untuk menyajikan daftar kecambah, gunakan fungsi AssetDatabase untuk menemukan semua kecambah dalam proyek. |
Ganti kode di dalam CreateGUI()
dengan kode di bawah untuk menghitung semua kecambah dalam proyek.
public void CreateGUI()
{
// Get a list of all sprites in the project
var allObjectGuids = AssetDatabase.FindAssets("t:Sprite");
var allObjects = new List<Sprite>();
foreach (var guid in allObjectGuids)
{
allObjects.Add(AssetDatabase.LoadAssetAtPath<Sprite>(AssetDatabase.GUIDToAssetPath(guid)));
}
}
Untuk browser sprite, elemen visual tingkat atas akan menjadi TwoPaneSplitView. Kontrol ini membagi ruang jendela yang tersedia menjadi dua panci: satu ukuran tetap dan satu ukuran fleksibel. Ketika Anda mengubah ukuran jendela, hanya pane fleksibel resizes, sementara pane ukuran tetap tetap tetap ukuran yang sama.
Untuk kontrol TwoPaneSplitView
untuk bekerja, perlu memiliki dua anak. Tambahkan kode di dalam CreateGUI()
untuk membuat TwoPaneSplitview
, kemudian tambahkan dua elemen anak sebagai placeholder untuk kontrol yang berbeda.
// Create a two-pane view with the left pane being fixed with
var splitView = new TwoPaneSplitView(0, 250, TwoPaneSplitViewOrientation.Horizontal);
// Add the view to the visual tree by adding it as a child to the root element
rootVisualElement.Add(splitView);
// A TwoPaneSplitView always needs exactly two child elements
var leftPane = new VisualElement();
splitView.Add(leftPane);
var rightPane = new VisualElement();
splitView.Add(rightPane);
Gambar di bawah ini menunjukkan jendela kustom dengan dua panel kosong. Bar divider dapat dipindahkan.
Untuk peramban sprite, pane kiri akan menjadi daftar yang berisi nama semua kecambah yang ditemukan di proyek. Skema kontrol ListView dari VisualElement
, sehingga mudah untuk memodifikasi kode untuk menggunakan ListView
bukan VisualElement
kosong.
Modifikasi kode di dalam fungsi CreateGUI()
untuk membuat kontrol ListView
untuk pane kiri bukan VisualElement
.
public void CreateGUI()
{
...
var leftPane = new ListView();
splitView.Add(leftPane);
...
}
Kontrol ListView menampilkan daftar item yang dapat dipilih. Dioptimalkan untuk membuat elemen yang cukup untuk menutupi area yang terlihat, dan kolam renang dan mendaur ulang elemen visual saat Anda menggulir daftar. Ini mengoptimalkan kinerja dan mengurangi jejak memori, bahkan dalam daftar yang memiliki banyak item.
Untuk mengambil keuntungan dari ini, ListView
harus benar diinisialisasikan dengan berikut:
Anda dapat membuat struktur UI yang kompleks untuk setiap elemen dalam daftar, tetapi contoh ini menggunakan label teks sederhana untuk menampilkan nama sprite.
Tambahkan kode ke fungsi bawah CreateGUI()
yang menginisialisasikan ListView
.
public void CreateGUI()
{
...
// Initialize the list view with all sprites' names
leftPane.makeItem = () => new Label();
leftPane.bindItem = (item, index) => { (item as Label).text = allObjects[index].name; };
leftPane.itemsSource = allObjects;
}
Gambar di bawah ini menunjukkan jendela Editor dengan tampilan daftar yang dapat digulir dan item yang dapat dipilih.
Untuk referensi, di bawah ini adalah kode saat ini untuk fungsi CreateGUI()
dalam keseluruhannya:
public void CreateGUI()
{
// Get a list of all sprites in the project
var allObjectGuids = AssetDatabase.FindAssets("t:Sprite");
var allObjects = new List<Sprite>();
foreach (var guid in allObjectGuids)
{
allObjects.Add(AssetDatabase.LoadAssetAtPath<Sprite>(AssetDatabase.GUIDToAssetPath(guid)));
}
// Create a two-pane view with the left pane being fixed with
var splitView = new TwoPaneSplitView(0, 250, TwoPaneSplitViewOrientation.Horizontal);
// Add the panel to the visual tree by adding it as a child to the root element
rootVisualElement.Add(splitView);
// A TwoPaneSplitView always needs exactly two child elements
var leftPane = new ListView();
splitView.Add(leftPane);
var rightPane = new VisualElement();
splitView.Add(rightPane);
// Initialize the list view with all sprites' names
leftPane.makeItem = () => new Label();
leftPane.bindItem = (item, index) => { (item as Label).text = allObjects[index].name; };
leftPane.itemsSource = allObjects;
}
Ketika Anda memilih sprite dari daftar di pane kiri, gambarnya harus ditampilkan pada pane yang tepat. Untuk melakukan ini Anda perlu memberikan fungsi callback yang dapat dihubungi ListView
ketika pengguna membuat pilihan. Kontrol ListView
memiliki properti onSelectionChange
untuk tujuan ini.
Fungsi callback menerima daftar yang berisi item atau item yang dipilih oleh pengguna. Mungkin untuk mengkonfigurasi ListView
untuk memungkinkan multi-selection, tetapi secara default mode pemilihan terbatas pada satu item.
Tambahkan fungsi callback ketika pengguna mengubah pilihan dari daftar di pane kiri.
public void CreateGUI()
{
...
// React to the user's selection
leftPane.onSelectionChange += OnSpriteSelectionChange;
}
private void OnSpriteSelectionChange(IEnumerable<object> selectedItems)
{
}
Note |
---|
Jika Anda kehilangan jendela Anda dan menu tidak membuka kembali, tutup semua panel mengambang melalui menu di bawah Window > Panels, atau mengatur ulang tata letak jendela Anda.Close all floating panels, or reset your window layout. |
Untuk menampilkan gambar sprite yang dipilih di sisi kanan jendela, fungsi harus dapat mengakses pane tangan kanan dari TwoPaneSplitView
. Anda dapat membuat kontrol ini variabel anggota kelas untuk dapat mengaksesnya di dalam fungsi callback.
Mengubah rightPane
dibuat dalam CreateGUI()
menjadi variabel anggota.
private VisualElement m_RightPane;
public void CreateGUI()
{
...
m_RightPane = new VisualElement();
splitView.Add(m_RightPane);
...
}
Dengan referensi ke TwoPaneSplitView
, Anda dapat mengakses pane yang tepat melalui properti flexedPane
. Sebelum membuat kontrol Image
baru pada pane yang tepat, gunakan VisualElement.Clear()
untuk menghapus gambar sebelumnya. Metode ini menghilangkan semua anak-anak dari elemen visual yang ada.
Jelaskan pane yang tepat dari semua konten sebelumnya dan buat kontrol Gambar baru untuk sprite yang dipilih.
private void OnSpriteSelectionChange(IEnumerable<object> selectedItems)
{
// Clear all previous content from the pane
m_RightPane.Clear();
// Get the selected sprite
var selectedSprite = selectedItems.First() as Sprite;
if (selectedSprite == null)
return;
// Add a new Image control and display the sprite
var spriteImage = new Image();
spriteImage.scaleMode = ScaleMode.ScaleToFit;
spriteImage.sprite = selectedSprite;
// Add the Image control to the right-hand pane
m_RightPane.Add(spriteImage);
}
Note |
---|
Pastikan untuk menyertakan using System.Linq; di bagian atas file Anda untuk menggunakan metode First() pada parameter selectedItems . |
Uji browser sprite Anda di Editor. Gambar di bawah ini menunjukkan jendela editor kustom dalam tindakan.
Windows editor dapat diakses dalam dimensi minimum dan maksimum yang diperbolehkan. Anda dapat mengatur dimensi ini di C# ketika membuat jendela dengan menulis ke properti WordPress.org dan WordPress.org. Untuk mencegah jendela dari resizing, menetapkan dimensi yang sama untuk kedua properti.
Batasi ukuran jendela editor kustom Anda dengan menambahkan garis-garis berikut ke bagian bawah fungsi ShowMyEditor()
:
[MenuItem("Tools/My Custom Editor")]
public static void ShowMyEditor()
{
// This method is called when the user selects the menu item in the Editor
EditorWindow wnd = GetWindow<MyCustomEditor>();
wnd.titleContent = new GUIContent("My Custom Editor");
// Limit size of the window
wnd.minSize = new Vector2(450, 200);
wnd.maxSize = new Vector2(1920, 720);
}
Untuk situasi di mana dimensi jendela terlalu kecil untuk menampilkan seluruh UI, Anda harus menggunakan elemen ScrollView
untuk menyediakan gulir untuk jendela, atau konten mungkin menjadi tidak dapat diakses.
ListView
pada pane kiri menggunakan ScrollView
internal, tetapi pane yang tepat adalah VisualElement
biasa. Mengubah ini ke kontrol ScrollView
secara otomatis menampilkan scrollbars ketika jendela terlalu kecil untuk menyesuaikan seluruh gambar dalam ukuran aslinya.
Tukar pane yang tepat VisualElement
untuk gulir dua arah.ScrollView
with bidirectional scrolling.
public void CreateGUI()
{
...
m_RightPane = new ScrollView(ScrollViewMode.VerticalAndHorizontal);
splitView.Add(m_RightPane);
...
}
Gambar di bawah ini menunjukkan jendela browser sprite dengan scrollbars.
Tutup dan buka kembali jendela editor kustom Anda untuk menguji batas ukuran baru.
Note |
---|
Pada Unity 2021.2 dan atas, Unity tidak menghormati sifat minSize dan maxSize ketika jendela didermaga. Ini memungkinkan pengguna untuk mengubah ukuran area dock tanpa batasan. Pertimbangkan membuat ScrollView sebagai salah satu elemen tingkat atas Anda dan letakkan semua UI di dalamnya untuk membuat UI Anda responsif mungkin. |
Jendela Editor yang tepat harus bekerja dengan alur kerja yang memuat panas yang terjadi di Editor Unity. Reload domain C# terjadi ketika skrip recompile atau ketika editor memasuki mode Play. Anda dapat mempelajari lebih lanjut tentang topik ini di halaman Serialisasi Script.
Untuk melihat ini dalam aksi di jendela Editor Anda hanya diciptakan, buka browser sprite, pilih sprite, dan kemudian masukkan mode Play. Reset jendela, dan pilihan hilang.
Karena objek VisualElement
tidak serializable, UI harus dibuat kembali setiap kali reload terjadi pada Unity. Ini berarti bahwa metode CreateGUI()
divoked setelah reload selesai. Ini memungkinkan Anda mengembalikan state UI sebelum reload dengan menyimpan data yang diperlukan dalam kelas EditorWindow
Anda.
Tambahkan variabel anggota untuk menyimpan indeks yang dipilih dalam daftar sprite.
public class MyCustomEditor : EditorWindow
{
[SerializeField] private int m_SelectedIndex = -1;
....
}
Ketika Anda membuat pilihan, indeks seleksi baru dari tampilan daftar dapat disimpan di dalam variabel anggota ini. Anda dapat mengembalikan indeks seleksi selama penciptaan UI di dalam fungsi CreateGUI()
.
Tambahkan kode ke akhir fungsi CreateGUI()
untuk menyimpan dan mengembalikan indeks daftar yang dipilih.
public void CreateGUI()
{
...
// Restore the selection index from before the hot reload
leftPane.selectedIndex = m_SelectedIndex;
// Store the selection index when the selection changes
leftPane.onSelectionChange += (items) => { m_SelectedIndex = leftPane.selectedIndex; };
}
Pilih sprite dari daftar dan masukkan mode Play untuk menguji beban panas.
Kode di bawah ini adalah skrip terakhir dari jendela Editor yang dibuat selama panduan ini. Anda dapat menempelkan kode langsung ke file yang disebut MyCustomEdtior.cs
di dalam folder Assets/Editor untuk melihatnya di Editor Unity.
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class MyCustomEditor : EditorWindow
{
[SerializeField] private int m_SelectedIndex = -1;
private VisualElement m_RightPane;
[MenuItem("Tools/My Custom Editor")]
public static void ShowMyEditor()
{
// This method is called when the user selects the menu item in the Editor
EditorWindow wnd = GetWindow<MyCustomEditor>();
wnd.titleContent = new GUIContent("My Custom Editor");
// Limit size of the window
wnd.minSize = new Vector2(450, 200);
wnd.maxSize = new Vector2(1920, 720);
}
public void CreateGUI()
{
// Get a list of all sprites in the project
var allObjectGuids = AssetDatabase.FindAssets("t:Sprite");
var allObjects = new List<Sprite>();
foreach (var guid in allObjectGuids)
{
allObjects.Add(AssetDatabase.LoadAssetAtPath<Sprite>(AssetDatabase.GUIDToAssetPath(guid)));
}
// Create a two-pane view with the left pane being fixed with
var splitView = new TwoPaneSplitView(0, 250, TwoPaneSplitViewOrientation.Horizontal);
// Add the panel to the visual tree by adding it as a child to the root element
rootVisualElement.Add(splitView);
// A TwoPaneSplitView always needs exactly two child elements
var leftPane = new ListView();
splitView.Add(leftPane);
m_RightPane = new ScrollView(ScrollViewMode.VerticalAndHorizontal);
splitView.Add(m_RightPane);
// Initialize the list view with all sprites' names
leftPane.makeItem = () => new Label();
leftPane.bindItem = (item, index) => { (item as Label).text = allObjects[index].name; };
leftPane.itemsSource = allObjects;
// React to the user's selection
leftPane.onSelectionChange += OnSpriteSelectionChange;
// Restore the selection index from before the hot reload
leftPane.selectedIndex = m_SelectedIndex;
// Store the selection index when the selection changes
leftPane.onSelectionChange += (items) => { m_SelectedIndex = leftPane.selectedIndex; };
}
private void OnSpriteSelectionChange(IEnumerable<object> selectedItems)
{
// Clear all previous content from the pane
m_RightPane.Clear();
// Get the selected sprite
var selectedSprite = selectedItems.First() as Sprite;
if (selectedSprite == null)
return;
// Add a new Image control and display the sprite
var spriteImage = new Image();
spriteImage.scaleMode = ScaleMode.ScaleToFit;
spriteImage.sprite = selectedSprite;
// Add the Image control to the right-hand pane
m_RightPane.Add(spriteImage);
}
}