Halaman ini akan memandu Anda melalui langkah-langkah untuk mengatur layar pemilihan karakter sederhana menggunakan UI(User Interface) Memungkinkan pengguna untuk berinteraksi dengan aplikasi Anda. Unity saat ini mendukung tiga sistem UI. More info
Lihat di Glossary Toolkit. Ini mencakup penciptaan elemen UI dan template, pengaturan 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 cara menghubungkan logika skrip ke UI. Panduan ini tidak akan menutupi styling melalui USS, dan hanya menggunakan gaya default dan mereka.
Anda dapat menemukan kode sumber akhir panduan ini di bagian bawah halaman ini here.
Topics covered: UI Builder, ListView, Label, PanelSettings, UIDocument, penanganan seleksi
Panduan ini akan membawa Anda melalui langkah-langkah berikut:
Layar UI akhir terdiri dari dua template UI individu (UXML). Templat tampilan utama berisi daftar dengan nama karakter, panel yang lebih kecil untuk menampilkan detail karakter yang dipilih, dan tombol. Di bagian ini Anda akan mengatur template ini menggunakan UI Builder.
Note: Jika Anda akrab dengan UI Builder dan ingin melewatkan langkah ini, Anda dapat menyalin kode UXML untuk main view dari bagian bawah halaman ini dan menempel ke file baru langsung. Simpan sebagai Assets/UI/MainView.uxml.
Buka jendela UI Builder melalui menu Window > UI Toolkit > UI Builder. Buat dokumen UX baru menggunakan menu file di sebelah kiri atas viewport.
Ketika mengembangkan UI permainan, selalu pastikan untuk memilih Unity Default Runtime Theme
di kanan atas viewportArea tampilan pengguna aplikasi di layar mereka.
Lihat di Glossary UI Builder. Ukuran dan warna font standar berbeda antara tema Editor dan Runtime dan yang mempengaruhi tata letak Anda.
Pilih file UX baru di kotak cek Hierarchy dan mengaktifkan kotak cemen. Anda mungkin perlu mengatur Editor Unity Anda ke resolusi lansekap jika Anda belum.Match Game View checkbox. You might need to set your Unity Editor to a landscape resolution if you haven’t already.
Sekarang saatnya membuat elemen UI! Buat VisualElement baru dengan menyeretnya dari Library ke dalam Hierarchy.
Elemen baru perlu menutupi seluruh layar, sehingga Anda perlu mengatur properti flex-grow
menjadi 1. Pilih elemen dari hirarki dan temukan lipatan label Flex di panel 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 di sebelah kanan. Ubah nilai untuk Grow dari 0 sampai 1.
Untuk pusat semua anak-anak dari VisualElement ini di tengah layar, mengubah sifat Align dari VisualElement. Anda harus mengatur kedua Align Items dan Justify Content untuk center.
Terakhir, Anda dapat memilih warna latar belakang di bawah Background > Color. Langkah ini adalah opsional. Contoh ini menggunakan #732526
sebagai warna.
Selanjutnya, buat VisualElement baru di bawah yang ada. Ini akan menjadi wadah induk untuk bagian kiri dan kanan UI.
Mengatur properti flex-direction
untuk row
untuk elemen baru ini (secara default ke kolom). Anda juga perlu mengatur ketinggian tetap 350 pixelsUnit terkecil dalam gambar komputer. Ukuran piksel tergantung pada resolusi layar Anda. Pencahayaan pixel dihitung pada setiap piksel layar. More info
Lihat di Glossary.
Ini adalah apa UI saat ini harus terlihat seperti. Perhatikan bahwa layar Anda mungkin terlihat berbeda tergantung pada resolusi dan aspect ratioHubungan dimensi proporsional gambar, seperti lebar dan tingginya.
Lihat di Glossary dari Game View Anda.
Untuk membuat daftar nama karakter, pilih kontrol ListView dari Library dan menambahkannya sebagai anak di bawah VisualElement yang Anda buat. Pilih elemen dan menetapkan nama CharacterList
dalam inspektur. Hal ini diperlukan sehingga Anda dapat mengakses daftar ini melalui skrip pengontrol kemudian.
Mengatur daftar untuk memiliki lebar tetap 230 piksel. Juga memberikan margin lebar 6 px di sebelah kanan, untuk menukar beberapa jarak ke elemen berikutnya yang akan Anda buat.
Anda juga dapat menetapkan warna latar belakang dan menetapkan batas bulat untuk daftar. Panduan ini menggunakan #6E3925
untuk latar belakang dan #311A11
untuk warna perbatasan, dengan batas lebar 4px dan radius 15px. Langkah ini adalah opsional.
Tambahkan VisualElement baru di bawah induk yang sama dengan CharacterList
. Ini akan memegang panel detail karakter dan tombol. Di bawah lipatan Align, ubah pengaturan untuk Align Items ke flex-end
, dan Justify Content ke space-between
.
Tambahkan VisualElement baru ke wadah baru ini. Ini akan menjadi panel detail karakter. Ketika pengguna memilih karakter dari daftar di sebelah kiri, itu akan menampilkan potret karakter, nama, dan kelas.
Tetapkan lebar 276 piksel untuk elemen, dan beralih Align Items dan Justify Content ke center. Juga tambahkan bantalan lebar 8 piksel untuk elemen, sehingga anak-anak akan menjaga jarak minimum ke perbatasan wadah.
Anda dapat menata panel dengan mengatur warna latar belakang #AA5939
dan warna perbatasan #311A11
dengan batas lebar 4px dan radius 15px. Langkah ini adalah opsional.
Tata letak UI Anda sekarang harus terlihat mirip dengan gambar di bawah ini.
Selanjutnya Anda akan menambahkan kontrol UI individu ke rincian karakter. Pertama adalah potret karakter. Ini terdiri dari dua elemen - bingkai di latar belakang dan gambar di latar belakang.
Tambahkan VisualElement baru ke wadah detail karakter untuk bingkai latar belakang terlebih dahulu. Masukkan ukuran tetap 120 × 120 piksel, dan bantalan 4 piksel sehingga gambar yang terkandung tidak akan langsung menyentuh perbatasan.
Anda dapat menggunakan batas radius 2px-wide, 15px dengan warna #311A11
dan warna latar belakang #FF8554
untuk memberi gaya elemen. Jangan ragu untuk menerapkan warna dan styling Anda sendiri.
Untuk gambar aktual menambahkan VisualElement baru sebagai anak ke bingkai yang Anda buat. Nama itu CharacterPortrait
sehingga Anda dapat mengaksesnya di skrip pengontrol kemudian.
Set Flex > Grow ke 1, sehingga gambar menggunakan semua ruang yang tersedia. Juga pastikan untuk mengubah mode scaling di bawah Background > Scale Mode ke scale-to-fit
, sehingga Anda dapat mengukur gambar sesuai dengan ukuran elemen, sambil menjaga rasio aspek yang benar.
Selanjutnya, tambahkan dua kontrol label ke wadah detail karakter, yang kemudian Anda gunakan untuk menampilkan nama dan kelas karakter yang dipilih. Nama mereka CharacterName
dan CharacterClass
.
Untuk membuat nama karakter menonjol lebih dari kelas, mengubah ukuran font label menjadi 18, dan mengatur gaya ke bold.
Layar UI Anda sekarang harus terlihat mirip dengan gambar di bawah ini.
Terakhir, tambahkan kontrol tombol ke wadah UI sisi kanan. Anda kemudian akan mengakses tombol ini di script controller dan mengaktifkan atau menonaktifkannya ketika karakter dipilih atau dipilih. Nama tombol SelectCharButton
dan memberikan lebar tetap 150px. Anda juga harus mengatur teks label dari tombol ke Select Character
.
Untuk memberi gaya tombol, atur warna latar belakang #FF8554
, dan perbatasan 2px dengan warna #311A11
. Langkah ini adalah opsional.
Tampilan utama selesai Anda harus terlihat mirip dengan gambar di bawah ini.
Simpan template UXML sebagai Assets/UI/MainView.uxml. Anda juga dapat menemukan kode UXML terakhir untuk template ini di bagian bawah halaman here.
Di bagian ini Anda akan belajar cara memuat dan menampilkan template UI yang Anda buat di bagian sebelumnya dalam permainan Anda saat ini.
Untuk memulai Anda perlu membuat aset PanelSettings. aset ini akan menentukan pengaturan layar Anda, seperti mode scaling dan urutan rendering. Ini juga akan menentukan nama di mana UI Anda akan muncul di UI Toolkit Debugger.
Buat Panel Settings Asset
baru dengan klik kanan dalam tampilan proyek. Pilih Create > UI Toolkit > Panel Settings Asset. Nama file yang baru dibuat GameUI_Panel
. Untuk panduan ini Anda dapat meninggalkan semua pengaturan pada nilai default mereka.
Untuk menampilkan templat UI tampilan utama dari bagian sebelumnya Anda perlu membuat 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 tempat kejadian. Pasang komponen UIDocument untuk itu.
UIDocument
akan secara otomatis memuat VisualTreeAsset
yang ditugaskan saat memasukkan mode Play di Unity. A VisualTreeAsset
adalah template UXML. Masukkan pengaturan panel MainView.uxml
dan panel GameUI_Panel
baru ke komponen.
Note: Jika Anda tidak menetapkan aset PanelSettings
ke komponen Dokumen UI Anda, akan secara otomatis mencari proyek dan menggunakan Aset Pengaturan Panel pertama yang ditemukan secara otomatis. Ingatlah hal ini ketika renaming atau bergerak aset.
Anda sekarang dapat memasukkan mode Play di Editor Unity dan lihat UI Anda ditampilkan dalam tampilan permainan.
Note: Jika Anda memiliki beberapa Dokumen UI di tempat kejadian Anda, Anda dapat menetapkan aset pengaturan panel yang sama untuk semua. Ini akan menyebabkan semua UI yang akan diberikan pada panel yang sama, mengoptimalkan kinerja.
Di bagian ini Anda akan membuat beberapa data sampel yang akan digunakan untuk mengisi daftar karakter di UI dengan data.
Untuk daftar karakter Anda perlu kelas sederhana yang memegang nama karakter, kelas, dan gambar potret. Buat script ScriptableObject baru Assets/ScriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary/CharacterData.cs dan paste kode berikut ke file:
using UnityEngine;
public enum ECharacterClass
{
Knight, Ranger, Wizard
}
[CreateAssetMenu]
public class CharacterData : ScriptableObject
{
public string m_CharacterName;
public ECharacterClass m_Class;
public Sprite m_PortraitImage;
}
Atribut [CreateAssetMenu]
akan secara otomatis menambahkan entri ke menu Create. Klik kanan ke folder dalam tampilan Proyek untuk membuat instance dari ScriptableObject baru.
Sekarang Anda perlu membuat beberapa contoh CharacterData
dan mengisinya dengan data acak. Tempatkan semua di folder Resources/Characters. Anda akan menulis script yang secara otomatis parses dan memuat semua data karakter dari folder ini nanti.
Di bagian ini Anda akan membuat template UI untuk entri individu dalam daftar. Pada runtime, skrip pengontrol akan membuat instance UI ini untuk setiap karakter dan menambahkannya ke daftar. UI untuk entri daftar karakter terdiri dari bingkai latar belakang berwarna dan nama karakter.
Note: Jika Anda ingin melewatkan langkah ini, Anda dapat menyalin kode UXML untuk list entry dari bagian bawah halaman ini dan menempel ke file baru langsung. Simpan sebagai Assets/UI/ListEntry.uxml.
Buka jendela UI Builder melalui menu Window > UI Toolkit > UI Builder. Buat template UX baru dengan memilih File > New.
Tambahkan VisualElement untuk latar belakang, dan atur heigth tetap 41px. Karena teks di dalam entri harus disampingkan dan ditempatkan di tengah elemen, buka lipatan Align dan set Align Items ke left, dan Justify Content ke center. Juga mengatur bantalan kiri 10px, untuk membuat label memiliki jarak minimum ke perbatasan kiri bingkai.
Untuk styling, Anda dapat menggunakan #AA5939
untuk warna latar belakang dan menambahkan batas lebar 2px, dengan radius 15px dan warna #311A11
. Langkah ini adalah opsional dan Anda dapat menerapkan warna dan styling Anda sendiri.
Tambahkan label sebagai anak ke VisualElement yang ada dan nama CharacterName
, sehingga Anda dapat mengaksesnya nanti di skrip pengontrol. Mengatur Font Style ke bold dan ukuran font ke 18.
Simpan template UXML sebagai Assets/UI/ListEntry.uxml. Anda juga dapat menemukan kode UXML terakhir untuk template ini di bagian bawah halaman here.
Di bagian ini Anda akan membuat skrip pengontrol untuk entri daftar. Tujuan dari script adalah untuk menampilkan data instance karakter di UI entri daftar. Perlu mengakses label untuk nama karakter dan mengaturnya untuk menampilkan nama instance karakter yang diberikan.
Buat skrip baru Assets/Scripts/UI/CharacterListEntryController.cs dan tempelkan kode berikut ke dalamnya:
using UnityEngine.UIElements;
public class CharacterListEntryController
{
Label m_NameLabel;
public void SetVisualElement(VisualElement visualElement)
{
m_NameLabel = visualElement.Q<Label>("CharacterName");
}
public void SetCharacterData(CharacterData characterData)
{
m_NameLabel.text = characterData.m_CharacterName;
}
}
Ada dua fungsi di kelas ini, dan keduanya adalah fungsi Set
.
Sitemap Fungsi ini akan menerima elemen visual yang merupakan contoh template UI SetVisualElement(VisualElement visualElement)
yang Anda buat di bagian sebelumnya. Pengontrol tampilan utama akan membuat instance ini. Tujuan dari fungsi ini adalah untuk mengambil referensi ke label nama karakter di dalam elemen UI.ListEntry
UI template you created in the previous section. The main view controller will create this instance. The purpose of this function is to retrieve a reference to the character name label inside the UI element.
Sitemap Fungsi ini menerima karakter yang namanya elemen daftar ini seharusnya ditampilkan. Karena elemen-elemen daftar dalam SetCharacterData(CharacterData characterData)
di kolamkan dan digunakan kembali, perlu memiliki fungsi ListView
untuk mengubah data karakter yang ditampilkan.Set
function to change which character’s data to display.
Catatan bahwa kelas CharacterListEntry
bukan MonoBehaviour
. Karena elemen visual dalam UI Toolkit bukan GameObjects, Anda tidak dapat melampirkan komponen kepada mereka. Sebagai gantinya, kelas ini akan melekat pada properti userData
di bagian berikutnya.
Di bagian ini Anda akan membuat skrip pengontrol untuk daftar karakter dalam pandangan utama, dan skrip MonoBehaviour yang mengintip dan menetapkannya ke pohon visual.
Untuk memulai, buat skrip baru di bawah Assets/Scripts/UI/CharacterListController.cs dan tempelkan kode berikut ke dalamnya.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class CharacterListController
{
public void InitializeCharacterList(VisualElement root, VisualTreeAsset listElementTemplate)
{
}
}
Anda akan mengisi metode InitializeCharacterList()
akhir, tetapi penting untuk menambahkan metode kosong sekarang, sehingga Anda dapat menyebutnya di bagian berikutnya.
Attach the controller script to the main view
Sama seperti CharacterListEntryController
, CharacterListController
bukan MonoBehaviour
, dan perlu melekat pada pohon visual dengan cara yang berbeda. Anda perlu membuat skrip MonoBehaviour yang dapat dilampirkan ke GameObject yang sama sebagai UIDocument
. Ini akan melelahkan CharacterListController
dan melampirkannya ke Pohon Visual.
Buat skrip baru Assets/Scripts/UI/MainView.cs dan tempelkan kode berikut ke dalamnya:
using UnityEngine;
using UnityEngine.UIElements;
public class MainView : MonoBehaviour
{
[SerializeField]
VisualTreeAsset m_ListEntryTemplate;
void OnEnable()
{
// The UXML is already instantiated by the UIDocument component
var uiDocument = GetComponent<UIDocument>();
// Initialize the character list controller
var characterListController = new CharacterListController();
characterListController.InitializeCharacterList(uiDocument.rootVisualElement, m_ListEntryTemplate);
}
}
Pergi ke Editor Unity dan melampirkan skrip ke GameObject yang sama yaitu UIDocument
. Menetapkan properti ListEntry.uxml
ke List Entry Template.
Tidak ada kebutuhan untuk komponen skrip Anda untuk mengikut UXML MainView, karena ini dilakukan secara otomatis dalam komponen UIDocument
pada GameObject yang sama. Skrip MainView
mengakses komponen Kardiocument untuk mendapatkan referensi Pohon Visual yang sudah sesaat. Ini kemudian membuat contoh CharacterListController
dan melewati elemen akar pohon visual dan template UXML yang digunakan untuk elemen daftar individu.
Note: Ketika UI diisi ulang, pendamping komponen MonoBehaviour pada GameObject yang sama yang mengandung komponen UIDocument
akan dinonaktifkan sebelum reload, dan kemudian diperbaharui kembali setelah reload. Oleh karena itu praktik yang baik untuk menempatkan kode yang berinteraksi dengan UI dalam metode OnEnable
dan OnDisable
MonoBehaviours ini.
Enumerate all character data instances
Fungsi pertama yang harus Anda tambahkan ke skrip pengontrol adalah fungsi yang mengakibatkan semua instance data karakter yang Anda buat sebelumnya. Ini akan digunakan untuk mengisi daftar.
Salin kode di bawah ke kelas CharacterListController
.
List<CharacterData> m_AllCharacters;
void EnumerateAllCharacters()
{
m_AllCharacters = new List<CharacterData>();
m_AllCharacters.AddRange(Resources.LoadAll<CharacterData>("Characters"));
}
Note: Kode ini mengasumsikan bahwa Anda membuat instance karakter di folder Resources/Characters. Anda mungkin perlu menyesuaikan nama folder sesuai jika Anda menempatkan karakter dalam folder yang berbeda.
Sekarang Anda perlu memanggil metode EnumerateAllCharacter
selama awalisasi. Tambahkan panggilan ke atas metode InitializeCharacterList
:
public void InitializeCharacterList(VisualElement root, VisualTreeAsset listElementTemplate)
{
EnumerateAllCharacters();
}
Get references to the UI elements
Di bagian ini Anda akan mengisi konten metode InitializeCharacterList
. Hal pertama metode ini perlu dilakukan adalah memperoleh referensi untuk semua UI individu mengontrol itu perlu untuk mengakses informasi tampilan. Gunakan keluarga UQuery API untuk mengambil kontrol UI individu dengan nama, kelas AS, jenis, atau kombinasi dari ini.
Memperpanjang kode di dalam kelas CharacterListController
dengan kode di bawah ini:
// UXML template for list entries
VisualTreeAsset m_ListEntryTemplate;
// UI element references
ListView m_CharacterList;
Label m_CharClassLabel;
Label m_CharNameLabel;
VisualElement m_CharPortrait;
Button m_SelectCharButton;
public void InitializeCharacterList(VisualElement root, VisualTreeAsset listElementTemplate)
{
EnumerateAllCharacters();
// Store a reference to the template for the list entries
m_ListEntryTemplate = listElementTemplate;
// Store a reference to the character list element
m_CharacterList = root.Q<ListView>("CharacterList");
// Store references to the selected character info elements
m_CharClassLabel = root.Q<Label>("CharacterClass");
m_CharNameLabel = root.Q<Label>("CharacterName");
m_CharPortrait = root.Q<VisualElement>("CharacterPortrait");
// Store a reference to the select button
m_SelectCharButton = root.Q<Button>("SelectCharButton");
}
Fill the list with entries
Selanjutnya Anda perlu mengisi daftar di layar dengan karakter yang Anda anggap dan dimuat sebelumnya. Untuk melakukannya Anda perlu membuat metode baru FillCharacterList
di dalam kelas CharacterListController
.
Mengisi ListView dengan elemen membutuhkan 4 langkah:
makeItem
functionbindItem
functionTujuan dari fungsi callback Login Artikel adalah untuk membuat pohon visual kecil mewakili UI satu item daftar, dan mengembalikan visualElement akar pohon ini.
Dalam kasus ini, callback makeItem
perlu mengulang template UXML yang Anda buat untuk entri daftar. Ini juga perlu membuat contoh skrip pengontrol CharacterListEntryController
, yang mengurus mengisi UI dengan data dari CharacterData
.
Buat metode FillCharacterList
di dalam kelas dan tempelkan kode di bawah ini.
void FillCharacterList()
{
// Set up a make item function for a list entry
m_CharacterList.makeItem = () =>
{
// Instantiate the UXML template for the entry
var newListEntry = m_ListEntryTemplate.Instantiate();
// Instantiate a controller for the data
var newListEntryLogic = new CharacterListEntryController();
// Assign the controller script to the visual element
newListEntry.userData = newListEntryLogic;
// Initialize the controller script
newListEntryLogic.SetVisualElement(newListEntry);
// Return the root of the instantiated visual tree
return newListEntry;
};
}
Sebagai bagian dari callback makeItem
, Anda menyimpan skrip pengontrol di dalam properti userData
elemen visual instan. Ini memungkinkan Anda untuk mengakses skrip pada waktu kemudian dan menetapkan karakter yang berbeda ke elemen daftar.
// Assign the controller script to the visual element
newListEntry.userData = newListEntryLogic;
Sebagai pengoptimalan memori dan kinerja, elemen daftar reuses ListView
bukan seketika satu elemen untuk setiap entri dalam daftar. Ini menciptakan elemen visual yang cukup untuk mengisi area yang terlihat, dan kemudian kolam renang dan menggunakannya sebagai daftar digulir.
Untuk alasan ini Anda perlu memberikan callback Login Artikel yang mengikat instance data Anda (dalam kasus ini CharacterData
) ke elemen daftar individu.
Memperpanjang metode FillCharacterList
dengan menambahkan kode di bawah.
// Set up bind function for a specific list entry
m_CharacterList.bindItem = (item, index) =>
{
(item.userData as CharacterListEntryController).SetCharacterData(m_AllCharacters[index]);
};
Callback bindItem
menerima referensi ke elemen visual akar untuk pohon visual entri daftar, dan indeks untuk data. Karena Anda menyimpan referensi ke CharacterListEntryController
di properti userData
elemen visual, kode dapat mengaksesnya dan langsung mengatur CharacterData
.
Terakhir Anda perlu mengatur tinggi item elemen dan memberikan referensi ke sumber data untuk daftar. Ini memberi tahu daftar berapa banyak elemen yang mengandung.
Memperpanjang metode FillCharacterList
dengan menambahkan kode di bawah.
// Set a fixed item height
m_CharacterList.fixedItemHeight = 45;
// Set the actual item's source list/array
m_CharacterList.itemsSource = m_AllCharacters;
Akhirnya, Anda perlu memanggil metode FillCharacterList
di akhir awalisasi. Tambahkan panggilan ke bagian bawah metode InitializeCharacterList
seperti yang ditunjukkan di bawah ini:
FillCharacterList();
Jika Anda memasukkan Play Mode sekarang, daftar karakter akan mengisi nama karakter yang Anda buat.
Anda dapat menemukan kode akhir untuk script CharacterListController
di bagian bawah panduan ini, here
Ketika pengguna memilih karakter, rincian karakter - yaitu potret, nama lengkap dan kelas - perlu ditampilkan di bagian detail karakter di sisi kanan layar. Juga, ketika karakter dipilih, tombol seleksi perlu diaktifkan. Ketika tidak ada karakter yang dipilih, tombol harus menonaktifkan lagi.
Perhatikan bahwa Anda sudah bisa klik dan pilih karakter dalam daftar Anda. Fungsi untuk pemilihan dan menyoroti adalah bagian dari kontrol ListView. Yang perlu Anda tambahkan adalah fungsi callback untuk bereaksi ketika pengguna mengubah pilihan dalam daftar. Kontrol ListView
berisi acara onSelectionChange
untuk tujuan ini:
Tambahkan kode berikut ke bagian bawah metode InitializeCharacterList
:
// Register to get a callback when an item is selected
m_CharacterList.onSelectionChange += OnCharacterSelected;
Sekarang Anda perlu menerapkan fungsi callback OnCharacterSelected
yang Anda set up di kode di atas. Fungsi ini akan menerima daftar semua item yang dipilih dalam daftar. Namun, karena Anda hanya mengizinkan pemilihan item tunggal, Anda dapat mengakses item yang dipilih langsung melalui properti Login Artikel daftar.
Salin kode di bawah ke kelas Anda:
void OnCharacterSelected(IEnumerable<object> selectedItems)
{
// Get the currently selected item directly from the ListView
var selectedCharacter = m_CharacterList.selectedItem as CharacterData;
}
Properti selectedItem
bisa kembali null. Ini adalah kasus jika tidak ada yang dipilih, atau pengguna menekan tombol ESC
untuk memilih segalanya. Kasus ini perlu ditangani terlebih dahulu.
Memperpanjang metode OnCharacterSelected
seperti yang ditunjukkan di bawah ini:
void OnCharacterSelected(IEnumerable<object> selectedItems)
{
// Get the currently selected item directly from the ListView
var selectedCharacter = m_CharacterList.selectedItem as CharacterData;
// Handle none-selection (Escape to deselect everything)
if (selectedCharacter == null)
{
// Clear
m_CharClassLabel.text = "";
m_CharNameLabel.text = "";
m_CharPortrait.style.backgroundImage = null;
// Disable the select button
m_SelectCharButton.SetEnabled(false);
return;
}
}
Jika seleksi valid, Anda perlu menampilkan rincian karakter di UI. Anda dapat mengakses label dan elemen visual gambar potret melalui referensi yang Anda ambil dalam metode InitializeCharacterList
kelas Anda.
Salin kode di bawah ke metode OnCharacterSelected
:
// Fill in character details
m_CharClassLabel.text = selectedCharacter.m_Class.ToString();
m_CharNameLabel.text = selectedCharacter.m_CharacterName;
m_CharPortrait.style.backgroundImage = new StyleBackground(selectedCharacter.m_PortraitImage);
// Enable the select button
m_SelectCharButton.SetEnabled(true);
Anda sekarang dapat memasukkan Play Mode dan melihat daftar pilihan karakter Anda dalam tindakan. Tekan tombol Escape
untuk memilih karakter.
Di bawah ini Anda dapat menemukan kode sumber penuh untuk semua file yang dibuat dalam panduan ini.
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement style="flex-grow: 1; align-items: center; justify-content: center; background-color: rgb(115, 37, 38);">
<ui:VisualElement style="flex-direction: row; height: 350px;">
<ui:ListView focusable="true" name="CharacterList" style="width: 230px; border-left-color: rgb(49, 26, 17); border-right-color: rgb(49, 26, 17); border-top-color: rgb(49, 26, 17); border-bottom-color: rgb(49, 26, 17); border-left-width: 4px; border-right-width: 4px; border-top-width: 4px; border-bottom-width: 4px; background-color: rgb(110, 57, 37); border-top-left-radius: 15px; border-bottom-left-radius: 15px; border-top-right-radius: 15px; border-bottom-right-radius: 15px; margin-right: 6px;" />
<ui:VisualElement style="justify-content: space-between; align-items: flex-end;">
<ui:VisualElement style="align-items: center; background-color: rgb(170, 89, 57); border-left-width: 4px; border-right-width: 4px; border-top-width: 4px; border-bottom-width: 4px; border-left-color: rgb(49, 26, 17); border-right-color: rgb(49, 26, 17); border-top-color: rgb(49, 26, 17); border-bottom-color: rgb(49, 26, 17); border-top-left-radius: 15px; border-bottom-left-radius: 15px; border-top-right-radius: 15px; border-bottom-right-radius: 15px; width: 276px; justify-content: center; padding-left: 8px; padding-right: 8px; padding-top: 8px; padding-bottom: 8px;">
<ui:VisualElement style="border-left-color: rgb(49, 26, 17); border-right-color: rgb(49, 26, 17); border-top-color: rgb(49, 26, 17); border-bottom-color: rgb(49, 26, 17); border-left-width: 2px; border-right-width: 2px; border-top-width: 2px; border-bottom-width: 2px; height: 120px; width: 120px; border-top-left-radius: 13px; border-bottom-left-radius: 13px; border-top-right-radius: 13px; border-bottom-right-radius: 13px; padding-left: 4px; padding-right: 4px; padding-top: 4px; padding-bottom: 4px; background-color: rgb(255, 133, 84);">
<ui:VisualElement name="CharacterPortrait" style="flex-grow: 1; -unity-background-scale-mode: scale-to-fit;" />
</ui:VisualElement>
<ui:Label text="Label" name="CharacterName" style="-unity-font-style: bold; font-size: 18px;" />
<ui:Label text="Label" display-tooltip-when-elided="true" name="CharacterClass" style="margin-top: 2px; margin-bottom: 8px; padding-top: 0; padding-bottom: 0;" />
</ui:VisualElement>
<ui:Button text="Select Character" display-tooltip-when-elided="true" name="SelectCharButton" style="width: 150px; border-left-color: rgb(49, 26, 17); border-right-color: rgb(49, 26, 17); border-top-color: rgb(49, 26, 17); border-bottom-color: rgb(49, 26, 17); background-color: rgb(255, 133, 84); border-left-width: 2px; border-right-width: 2px; border-top-width: 2px; border-bottom-width: 2px;" />
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement style="height: 41px; align-items: flex-start; justify-content: center; padding-left: 10px; background-color: rgba(170, 89, 57, 255); border-left-color: rgba(49, 26, 17, 255); border-right-color: rgba(49, 26, 17, 255); border-top-color: rgba(49, 26, 17, 255); border-bottom-color: rgba(49, 26, 17, 255); border-left-width: 2px; border-right-width: 2px; border-top-width: 2px; border-bottom-width: 2px; border-top-left-radius: 15px; border-bottom-left-radius: 15px; border-top-right-radius: 15px; border-bottom-right-radius: 15px;">
<ui:Label text="Label" display-tooltip-when-elided="true" name="CharacterName" style="-unity-font-style: bold; font-size: 18px;" />
</ui:VisualElement>
</ui:UXML>
using UnityEngine;
public enum ECharacterClass
{
Knight, Ranger, Wizard
}
[CreateAssetMenu]
public class CharacterData : ScriptableObject
{
public string m_CharacterName;
public ECharacterClass m_Class;
public Sprite m_PortraitImage;
}
using UnityEngine.UIElements;
public class CharacterListEntryController
{
Label m_NameLabel;
public void SetVisualElement(VisualElement visualElement)
{
m_NameLabel = visualElement.Q<Label>("CharacterName");
}
public void SetCharacterData(CharacterData characterData)
{
m_NameLabel.text = characterData.m_CharacterName;
}
}
using UnityEngine;
using UnityEngine.UIElements;
public class MainView : MonoBehaviour
{
[SerializeField]
VisualTreeAsset m_ListEntryTemplate;
void OnEnable()
{
// The UXML is already instantiated by the UIDocument component
var uiDocument = GetComponent<UIDocument>();
// Initialize the character list controller
var characterListController = new CharacterListController();
characterListController.InitializeCharacterList(uiDocument.rootVisualElement, m_ListEntryTemplate);
}
}
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class CharacterListController
{
// UXML template for list entries
VisualTreeAsset m_ListEntryTemplate;
// UI element references
ListView m_CharacterList;
Label m_CharClassLabel;
Label m_CharNameLabel;
VisualElement m_CharPortrait;
Button m_SelectCharButton;
public void InitializeCharacterList(VisualElement root, VisualTreeAsset listElementTemplate)
{
EnumerateAllCharacters();
// Store a reference to the template for the list entries
m_ListEntryTemplate = listElementTemplate;
// Store a reference to the character list element
m_CharacterList = root.Q<ListView>("CharacterList");
// Store references to the selected character info elements
m_CharClassLabel = root.Q<Label>("CharacterClass");
m_CharNameLabel = root.Q<Label>("CharacterName");
m_CharPortrait = root.Q<VisualElement>("CharacterPortrait");
// Store a reference to the select button
m_SelectCharButton = root.Q<Button>("SelectCharButton");
FillCharacterList();
// Register to get a callback when an item is selected
m_CharacterList.onSelectionChange += OnCharacterSelected;
}
List<CharacterData> m_AllCharacters;
void EnumerateAllCharacters()
{
m_AllCharacters = new List<CharacterData>();
m_AllCharacters.AddRange(Resources.LoadAll<CharacterData>("Characters"));
}
void FillCharacterList()
{
// Set up a make item function for a list entry
m_CharacterList.makeItem = () =>
{
// Instantiate the UXML template for the entry
var newListEntry = m_ListEntryTemplate.Instantiate();
// Instantiate a controller for the data
var newListEntryLogic = new CharacterListEntryController();
// Assign the controller script to the visual element
newListEntry.userData = newListEntryLogic;
// Initialize the controller script
newListEntryLogic.SetVisualElement(newListEntry);
// Return the root of the instantiated visual tree
return newListEntry;
};
// Set up bind function for a specific list entry
m_CharacterList.bindItem = (item, index) =>
{
(item.userData as CharacterListEntryController).SetCharacterData(m_AllCharacters[index]);
};
// Set a fixed item height
m_CharacterList.fixedItemHeight = 45;
// Set the actual item's source list/array
m_CharacterList.itemsSource = m_AllCharacters;
}
void OnCharacterSelected(IEnumerable<object> selectedItems)
{
// Get the currently selected item directly from the ListView
var selectedCharacter = m_CharacterList.selectedItem as CharacterData;
// Handle none-selection (Escape to deselect everything)
if (selectedCharacter == null)
{
// Clear
m_CharClassLabel.text = "";
m_CharNameLabel.text = "";
m_CharPortrait.style.backgroundImage = null;
// Disable the select button
m_SelectCharButton.SetEnabled(false);
return;
}
// Fill in character details
m_CharClassLabel.text = selectedCharacter.m_Class.ToString();
m_CharNameLabel.text = selectedCharacter.m_CharacterName;
m_CharPortrait.style.backgroundImage = new StyleBackground(selectedCharacter.m_PortraitImage);
// Enable the select button
m_SelectCharButton.SetEnabled(true);
}
}