Unity3D :创建列表视图运行时 UI
推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生
创建列表视图运行时 UI
版本: 2021.3+
此示例演示如何创建列表视图运行时用户界面
.此示例直接使用 UXML 和 USS 文件来创建 UI 的结构和样式。如果你不熟悉 UI 工具包,并且想要使用 UI 生成器创建 UI,请参阅使用 UI 生成器创建示例 UI。
示例概述
本示例创建一个简单的字符选择屏幕。单击左侧列表中的字符名称时,该字符的详细信息将显示在右侧。
您可以在此 GitHub 存储库中找到此示例创建的已完成文件。
先决条件
本指南适用于熟悉 Unity 编辑器、UI 工具包和 C# 脚本的开发人员。在开始之前,请熟悉以下内容:
- 用户体验
ListView
Label
PanelSettings
UIDocument
创建主 UI 文档
创建主视图 UI 文档和 USS 文件以设置视觉元素
.在 UI 文档中添加两个可视元素作为容器:一个包含字符名称列表,另一个包含所选字符的详细信息。
- 使用任何模板在 Unity 中创建项目。
- 在项目窗口
,创建一个名为以存储所有 UI 文档和样式表文件的文件夹。UI
- 在该文件夹中,创建一个以以下内容命名的 UI 文档:
UIMainView.uxml
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
4. 在该文件夹中,创建一个以以下内容命名的 USS 样式表:UIMainView.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 文档和样式表。字符列表条目由彩色背景框和字符名称组成。
- 在该文件夹中,创建一个以以下内容命名的 UI 文档:
UIListEntry.uxml
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
2. 在该文件夹中,创建一个以以下内容命名的样式表文件:UIListEntry.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 中的字符列表。对于字符列表,创建一个包含角色名称、类和肖像图像的类。
- 在“资产”文件夹中,创建一个名为用于存储 C# 的文件夹
Scripts
脚本
. - 在该文件夹中,创建一个以以下内容命名的 C# 脚本:
ScriptsCharacterData.cs
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;
}
3. 这将在“资产>创建”菜单中创建一个“字符数据”项。
4. 在“资产”文件夹中,创建一个名为 的文件夹。Resources
5. 在该文件夹中,创建一个名为的文件夹,用于存储所有示例字符数据。ResourcesCharacters
6. 在该文件夹中,右键单击并选择“创建>字符数据”以创建 的实例。CharactersScriptableObject
7. 创建更多实例并用占位符数据填充它们。CharacterData
设置场景
创建用户界面目录游戏对象
,并将 UI 文档添加为源资源。
- 在示例场景中,选择“游戏对象> UI 工具包”>“UI 文档”。
- 在“层次结构”窗口中选择 UIDocument 游戏对象。
- 将 MainView.uxml 从“项目”窗口拖到 UI 文档组件的“源资源”字段中检查员
窗。这会将源资源引用到 UXML 文件。
为列表条目和主视图创建控制器
使用以下类创建两个 C# 脚本:
- 一个类,用于在列表条目的 UI 中显示字符实例的数据。它需要访问字符名称的标签,并将其设置为显示给定字符实例的名称。
CharacterListEntryController
- 主视图中字符列表的类,以及实例化字符列表并将其分配给
CharacterListControllerMonoBehaviour
可视化树
.
注意:该类不是 .由于 UI 工具包中的可视元素不是游戏对象,因此无法将组件附加到它们。而是将类附加到类中的属性。CharacterListEntryControllerMonoBehaviouruserDataCharacterListController
- 在该文件夹中,创建一个名为以下内容的 C# 脚本:
ScriptsCharacterListEntryController.cs
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;
}
}
2. 在该文件夹中,创建一个以以下内容命名的 C# 脚本:ScriptsCharacterListController.cs
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);
}
}
将控制器脚本附加到主视图
不是 ,因此必须附加到可视化树。创建一个脚本,您可以将该脚本附加到与 UIDocument 相同的游戏对象。它实例化并将其附加到可视化树。CharacterListControllerMonoBehaviourMonoBehaviourCharacterListController
- 在该文件夹中,创建一个以以下内容命名的 C# 脚本:
ScriptsMainView.cs
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);
}
}
2. 在“示例场景”中,选择“UIDocument”。
3. 拖移以在“检查器”窗口中添加组件。MainView.cs
4. 将 ListEntry.uxml 拖到 ListEntry Template 字段。
5. 进入运行模式以查看游戏视图中显示的 UI。
由3D建模学习工作室整理翻译,转载请注明出处!