バージョン: 2021.3 以降
この例は、リストビューのランタイム UI の作成方法を示すものです。この例では、UXML ファイルと USS ファイルを直接使用して、UI の構造とスタイルを作成します。UI Toolkit を初めて使用し、UI Builder を使用して UI を作成したい場合は、UI Builder でのサンプル UI の作成 を参照してください。
この例は、簡単なキャラクター選択画面を作成します。左側のリストからキャラクター名をクリックすると、右側にキャラクターの詳細が表示されます。
この例で作成される完成されたファイルは、こちらの GitHub リポジトリ にあります。
このガイドは、Unity エディター、UI Toolkit、および C# スクリプトに精通している開発者を対象としています。始める前に、以下をよく理解してください。
* UXML
* ListView
* Label
* PanelSettings
* UIDocument
メインビューの UI ドキュメントと、ビジュアル要素のスタイルを設定するための USS ファイルを作成します。UI ドキュメントにコンテナとして 2 つのビジュアル要素を追加します。1 つはキャラクター名のリスト、もう 1 つは選択されたキャラクターの詳細を含みます。
Unity で任意のテンプレートでプロジェクトを作成します。
Project ウィンドウで、全ての UI ドキュメントとスタイルシートファイルを格納するための UI
という名前のフォルダーを作成します。
UI
フォルダー内に、以下の内容を含む MainView.uxml
という UI ドキュメントを作成します。
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<Style src="MainView.uss" />
<ui:VisualElement name="background">
<ui:VisualElement name="main-container">
<ui:ListView focusable="true" name="character-list" />
<ui:VisualElement name="right-container">
<ui:VisualElement name="details-container">
<ui:VisualElement name="details">
<ui:VisualElement name="character-portrait" />
</ui:VisualElement>
<ui:Label text="Label" name="character-name" />
<ui:Label text="Label" display-tooltip-when-elided="true" name="character-class" />
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>
UI
フォルダー内に、以下の内容を含む MainView.uss
という USS スタイルシートを作成します。
#background {
flex-grow: 1;
align-items: center;
justify-content: center;
background-color: rgb(115, 37, 38);
}
#main-container {
flex-direction: row;
height: 350px;
}
#character-list {
width: 230px;
border-color: rgb(49, 26, 17);
border-width: 4px;
background-color: rgb(110, 57, 37);
border-radius: 15px;
margin-right: 6px;
}
#character-name {
-unity-font-style: bold;
font-size: 18px;
}
#CharacterClass {
margin-top: 2px;
margin-bottom: 8px;
padding-top: 0;
padding-bottom: 0;
}
#right-container{
justify-content: space-between;
align-items: flex-end;
}
#details-container{
align-items: center;
background-color: rgb(170, 89, 57);
border-width: 4px;
border-color: rgb(49, 26, 17);
border-radius: 15px;
width: 252px;
justify-content: center;
padding: 8px;
height: 163px;
}
#details{
border-color: rgb(49, 26, 17);
border-width: 2px;
height: 120px;
width: 120px;
border-radius: 13px;
padding: 4px;
background-color: rgb(255, 133, 84);
}
#character-portrait{
flex-grow: 1;
-unity-background-scale-mode: scale-to-fit;
}
リスト内の個々のエントリーの UI ドキュメントとスタイルシートを作成します。キャラクターリストのエントリーは、色付きの背景フレームとキャラクターの名前から構成されます。
UI
フォルダー内に、以下の内容を含む ListEntry.uxml
という UI ドキュメントを作成します。
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<Style src="ListEntry.uss" />
<ui:VisualElement name="list-entry">
<ui:Label text="Label" display-tooltip-when-elided="true" name="character-name" />
</ui:VisualElement>
</ui:UXML>
UI
フォルダー内に、以下の内容を含む ListEntry.uss
という名前のスタイルシートファイルを作成します。
#list-entry {
height: 41px;
align-items: flex-start;
justify-content: center;
padding-left: 10px;
background-color: rgb(170, 89, 57);
border-color: rgb(49, 26, 17);
border-width: 2px;
border-radius: 15px;
}
#character-name {
-unity-font-style: bold;
font-size: 18px;
color: rgb(49, 26, 17);
}
UI 内のキャラクターリストを埋めるサンプルデータを作成します。キャラクターリスト用に、キャラクター名、クラス、ポートレート画像を持つクラスを作成します。
Asset フォルダー内に、C# スクリプトを格納するための Scripts
というフォルダーを作成します。
Scripts
フォルダー内に、以下の内容を持つ CharacterData.cs
という名前の C# スクリプトを作成します。
using UnityEngine;
public enum ECharacterClass
{
Knight, Ranger, Wizard
}
[CreateAssetMenu] //This adds an entry to the **Create** menu
public class CharacterData : ScriptableObject
{
public string CharacterName;
public ECharacterClass Class;
public Sprite PortraitImage;
}
これにより、Assets > Create メニューに Character Data アイテムが作成されます。
Assets フォルダー内に、Resources
というフォルダーを作成します。
Resources
フォルダー内に、全てのサンプルキャラクターデータを格納するための Characters
というフォルダーを作成します。
Characters
フォルダー内で右クリックし、Create > Character Data を選択して ScriptableObject
のインスタンスを作成します。
CharacterData
インスタンスをさらに作成し、それらをプレースホルダーデータで埋めます。
サンプルシーン内に UIDocument ゲームオブジェクトを作成し、UI Document をソースアセットとして加えます。
以下のクラスを使用して 2 つの C# スクリプトを作成します。
CharacterListEntryController
クラス。これは、キャラクター名のラベルにアクセスし、指定のキャラクターインスタンスの名前を表示するためにそれを設定する必要があります。CharacterListController
クラスと、それをインスタンス化してビジュアルツリーに割り当てる MonoBehaviour
スクリプト。ノート: CharacterListEntry
クラスは MonoBehaviour
ではありません。UI Toolkit のビジュアル要素はゲームオブジェクトではないので、これにコンポーネントをアタッチすることはできません。代わりに、CharacterListController
クラス内の userData
プロパティにこのクラスをアタッチします。
Scripts
フォルダー内に、以下の内容を含む CharacterListEntryController.cs
という名前の C# スクリプトを作成します。
using UnityEngine.UIElements;
public class CharacterListEntryController
{
Label NameLabel;
//This function retrieves a reference to the
//character name label inside the UI element.
public void SetVisualElement(VisualElement visualElement)
{
NameLabel = visualElement.Q<Label>("character-name");
}
//This function receives the character whose name this list
//element displays. Since the elements listed
//in a `ListView` are pooled and reused, it's necessary to
//have a `Set` function to change which character's data to display.
public void SetCharacterData(CharacterData characterData)
{
NameLabel.text = characterData.CharacterName;
}
}
Scripts
フォルダー内に、以下の内容を含む CharacterListController.cs
という名前の C# スクリプトを作成します。
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class CharacterListController
{
// UXML template for list entries
VisualTreeAsset ListEntryTemplate;
// UI element references
ListView CharacterList;
Label CharClassLabel;
Label CharNameLabel;
VisualElement CharPortrait;
public void InitializeCharacterList(VisualElement root, VisualTreeAsset listElementTemplate)
{
EnumerateAllCharacters();
// Store a reference to the template for the list entries
ListEntryTemplate = listElementTemplate;
// Store a reference to the character list element
CharacterList = root.Q<ListView>("character-list");
// Store references to the selected character info elements
CharClassLabel = root.Q<Label>("character-class");
CharNameLabel = root.Q<Label>("character-name");
CharPortrait = root.Q<VisualElement>("character-portrait");
FillCharacterList();
// Register to get a callback when an item is selected
CharacterList.onSelectionChange += OnCharacterSelected;
}
List<CharacterData> AllCharacters;
void EnumerateAllCharacters()
{
AllCharacters = new List<CharacterData>();
AllCharacters.AddRange(Resources.LoadAll<CharacterData>("Characters"));
}
void FillCharacterList()
{
// Set up a make item function for a list entry
CharacterList.makeItem = () =>
{
// Instantiate the UXML template for the entry
var newListEntry = 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
CharacterList.bindItem = (item, index) =>
{
(item.userData as CharacterListEntryController).SetCharacterData(AllCharacters[index]);
};
// Set a fixed item height
CharacterList.fixedItemHeight = 45;
// Set the actual item's source list/array
CharacterList.itemsSource = AllCharacters;
}
void OnCharacterSelected(IEnumerable<object> selectedItems)
{
// Get the currently selected item directly from the ListView
var selectedCharacter = CharacterList.selectedItem as CharacterData;
// Handle none-selection (Escape to deselect everything)
if (selectedCharacter == null)
{
// Clear
CharClassLabel.text = "";
CharNameLabel.text = "";
CharPortrait.style.backgroundImage = null;
return;
}
// Fill in character details
CharClassLabel.text = selectedCharacter.Class.ToString();
CharNameLabel.text = selectedCharacter.CharacterName;
CharPortrait.style.backgroundImage = new StyleBackground(selectedCharacter.PortraitImage);
}
}
CharacterListController
は MonoBehaviour
ではないので、ビジュアルツリーにアタッチされる必要があります。同じゲームオブジェクトに UI ドキュメントとしてアタッチできる MonoBehaviour
スクリプトを作成してください。これが CharacterListController
をインスタンス化してビジュアルツリーにアタッチします。
Scripts
フォルダー内に、以下の内容を含む MainView.cs
という C# スクリプトを作成します。
using UnityEngine;
using UnityEngine.UIElements;
public class MainView : MonoBehaviour
{
[SerializeField]
VisualTreeAsset 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, ListEntryTemplate);
}
}
サンプルシーン内で UIDocument を選択します。
MainView.cs
を Inspector ウィンドウの Add Component にドラッグします。
ListEntry.uxml を ListEntry Template フィールドにドラッグします。
再生モードを開始すると、ゲームビューに UI が表示されます。
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.