Buat Inspektur Kustom
Pohon Visual

Membuat UI runtime pertama Anda

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:

  • Buat tampilan UI utama
  • Pengaturan adegan
  • Buat data sampel untuk ditampilkan
  • Buat controller untuk tampilan utama
  • Buat template UI entri daftar
  • Buat controller untuk entri daftar
  • Reaktor

Buat tampilan UI utama

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.

The UI layout setup for the main view
Pengaturan tata letak UI untuk tampilan utama

Buka jendela UI Builder melalui menu Window > UI Toolkit > UI Builder. Buat dokumen UX baru menggunakan menu file di sebelah kiri atas viewport.

UI Builder file menu
UI Builder menu

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.

Create new elements by dragging from the Library
Buat elemen baru dengan menyeret dari Perpustakaan

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.

Enabling Match Game View
Sitemap Tampilan Game

Sekarang saatnya membuat elemen UI! Buat VisualElement baru dengan menyeretnya dari Library ke dalam Hierarchy.

Create new elements by dragging from the Library
Buat elemen baru dengan menyeret dari Perpustakaan

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.

Setting the Flex property
Menyiapkan properti Flex

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.

Centering children
Berpusat anak-anak

Terakhir, Anda dapat memilih warna latar belakang di bawah Background > Color. Langkah ini adalah opsional. Contoh ini menggunakan #732526 sebagai warna.

Root element background color
Warna latar belakang elemen akar

Selanjutnya, buat VisualElement baru di bawah yang ada. Ini akan menjadi wadah induk untuk bagian kiri dan kanan UI.

Add a child VisualElement
Tambahkan VisualElement anak

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
.

Center container properties
Properti kontainer pusat

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.

Background container with empty element inside
Wadah latar belakang dengan elemen kosong di dalam

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.

Background container with empty element inside
Wadah latar belakang dengan elemen kosong di dalam

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.

Size and Margin foldouts for the character list
Ukuran dan lipatan Margin untuk daftar karakter

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.

Styled character list
Daftar karakter gaya

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.

Justify content property
Membenarkan properti konten

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.

Properties of the charcter details container
Properti dari wadah rincian charcter

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.

Empty character details panel
Panel rincian karakter kosong

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.

Background frame for the character portrait
Bingkai latar belakang untuk potret karakter

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.

VisualElement for the portrait image
Login Elemen untuk gambar potret

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.

Add labels for name and class
Tambahkan label untuk nama dan kelas

Untuk membuat nama karakter menonjol lebih dari kelas, mengubah ukuran font label menjadi 18, dan mengatur gaya ke bold.

Change font settings
Mengubah pengaturan font

Layar UI Anda sekarang harus terlihat mirip dengan gambar di bawah ini.

Finished character details panel
Panel detail karakter jadi

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.

Add button for character selection
Tambahkan tombol untuk pemilihan karakter

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.

Final main view layout
Tata letak tampilan utama akhir

Simpan template UXML sebagai Assets/UI/MainView.uxml. Anda juga dapat menemukan kode UXML terakhir untuk template ini di bagian bawah halaman here.

Pengaturan adegan

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.

Create a new panel settings asset
Buat aset pengaturan panel baru

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.

No need to change the default PanelSettings
Tidak perlu mengubah PanelSettings default

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.

The UI Document component
Komponen Dokumen UI

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.

UI displayed at runtime
UI ditampilkan di runtime

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.

Buat data sampel untuk ditampilkan

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.

New Create menu entry
Login menu

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.

Create a few sample characters
Buat beberapa karakter sampel

Buat template UI entri daftar

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.

List entry showing the character name
Daftar masuk menunjukkan 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.

Create a new UXML template in UI Builder
Buat template UX baru di UI Builder

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.

The background VisualElement
Latar belakang VisualElement

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.

Add label for the characters name
Tambahkan label untuk nama karakter

Simpan template UXML sebagai Assets/UI/ListEntry.uxml. Anda juga dapat menemukan kode UXML terakhir untuk template ini di bagian bawah halaman here.

Buat controller untuk entri daftar

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.

Buat controller untuk tampilan utama

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.

Add main view script and assign reference
Tambahkan skrip pandangan utama dan menetapkan referensi

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:

  1. Buat fungsi makeItem function
  2. Buat fungsi bindItem function
  3. Mengatur tinggi item
  4. Mengatur sumber item

Tujuan 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.

The character list is no longer empty
Daftar karakter tidak lagi kosong

Anda dapat menemukan kode akhir untuk script CharacterListController di bagian bawah panduan ini, here

Reaktor

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.

Final runtime UI
UI

Sitemap skrip akhirFinal scripts

Di bawah ini Anda dapat menemukan kode sumber penuh untuk semua file yang dibuat dalam panduan ini.

MainView.uxml

<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>

ListEntry.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>

CharacterData.cs

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;
}

CharacterListEntryController.cs

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;
    }
}

MainView.cs

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);
    }
}

CharacterListController.cs

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);
    }
}
Buat Inspektur Kustom
Pohon Visual