Create a ListView

Code and workflows for creating a dynamic UI ListView in UI Builder

What you'll develop on this page

Dynamic ListView that displays the name of GameObjects in a scene

Use UI Builder to create a dynamic UI ListView that displays GameObjects in a scene and responds to which item is clicked.

Github branch link: https://github.com/moetsi/Unity-DOTS-Multiplayer-XR-Sample/tree/Creating-a-List

What our ListView will do

We are going to build a ListView that displays the number of GameObjects with a "LocalGame" tag and the names of the corresponding GameObjects. When we click on the item in the list view we will be taken to the JoinGameScreen.

Just to be upfront, the approach we take to build this ListView is overkill for the number of GameObjects we will be counting. ListViews are good when all you want to do is bind data to visible items currently in the view and there are hundreds of items. As we scroll through the list, data will bind and appear and then unbind as we scroll past it. Again, this is overkill for just a few items, but we at Moetsi personally could not find any other resources published online explaining how to do this from scratch, so that just leaves us to do it!!!

We will create a new uxml file named "ListItem" that we will add and remove in the ListView. This is called "Instancing UI Documents as Templates" by Unity in their documentation. Next, we will make a ne w script named "LocalGamesFinder" that will power this new ListView. The reason it is called LocalGamesFinder is because we will be using it to find LAN games in the next Multiplayer section.

There are 3 spells you must cast to conjure ListView:

  • itemsSource (declares the data source of the items)

  • makeItem (creates the list item visual element from our uxml)

  • bindItem (attach the data from our itemsSource to our item)

When you update the data in itemsSource you can call Refresh() to update the list.

We do this differently in the next Multiplayer section, where we'll be listening for game broadcasts, and as new ones are found, we update our list.

In this page we will look for GameObjects in our scene and refresh our itemsSource 1x per second. This is not an optimal approach because it refreshes even when no items have changed, but it is fine to simply demonstrate the purposes of ListView.

Building our ListView

Creating ListItem uxml

Since we've already explained how to create and style uxmls using UI Builder on the previous page ("Styling a View"), we're going to just jump straight to the code here.

  • Create a new uxml file named ListItem (right-click in the UI folder, select Create, then UI Toolkit, and select UI Document)

  • and paste in the code snippet below:

  • Add the following classes at the bottom of TitleScreenUI USS (don't paste this snippet in over all your code!! Just add it to the bottom!)

Creating the ListItem uxml file and then adding more classes to TitleScreenUI
  • We will be taking the names of found GameObjects with "LocalGame" tags and inserting them in the label #game-name from the uxml

  • When we click on #join-local-game we will be taken to the local games view

Creating LocalGamesFinder

  • In NavigationScene, create an empty GameObject in the Hierarchy named "LocalGamesDiscovery"

  • Add component to LocalGamesDiscovery that is a new script named "LocalGamesFinder"

    • First make the file by right-clicking in the Scripts and Prefabs folder > Create > C# Script and name the file "LocalGamesFinder"

    • Then Navigate to LocalGamesDiscovery in Hierarchy and click Add Component in Inspector to add LocalGamesFinder

Creating LocalGamesDiscovery and LocalGamesFinder
  • Paste the code snippet below into LocalGamesFinder.cs:

Updating LocalGamesFinder
  • Let's also update our JoinGameScreen custom Visual Element (cVE) with the function that our ListItem button (join-local-game) calls, "LoadJoinScreenForSelectedServer"

  • To update, paste the code snippet below into JoinGameScreen.cs (cVE):

🔑MAJOR KEY ALERT🔑

The next few steps we take with LocalGamesFinder will show you a good approach for making scripts that interact with active UI. The general steps to follow are:

  • Make a public UI Document variable in your script

  • Drag your UI SourceAsset into that field in the Inspector from the scene's Hierarchy

  • Call .rootVisualElement on that variable

  • You can now query your entire Visual Element tree

  • Select LocalGamesDiscovery so LocalGamesFinder is visible in the Inspector

    • Drag the TitleScreenUI GameObject from the Hierarchy onto the "Title UI Document" field under Local Games Finder in Inspector

    • Drag ListItem from the Assets/UI folder in the Project folder to the "Local Game List Item Asset" field

Setting the public variables on LocalGamesFinder
  • In LoadJoinScreenForSelectedServer in JoinGameScreen cVE

    • We query for "game-name" and "game-ip" labels

    • We then set the text value of those labels to the name of our GameObjects

  • Delete the Debug.Log in "EnableJoinScreen()" in TitleScreenManager cVE

Updating JoinGameScreen cVE and
  • Now let's create an empty GameObject called LocalGame

  • Add a "LocalGame" tag to the LocalGame GameObject

    • To do this, you need to click the dropdown next to "Tag" in the Inspector when LocalGame is selected and choose the last option "Add Tag..." and click the + under Tags and type "LocalGame" to make a new tag

  • Copy and paste to make 10 copies

  • Let's hit play

    • Scroll up and down the list to see all our "LocalGames"

    • Copy and paste and make more GameObjects and see the ListView include those items

    • Click on Join button on one of the ListItems and check out the JoinGameScreen

    • Return back and click on another ListItem to see new data load

Creating LocalGame tagged GameObjects and seeing our ListView work
  • Place the LocalGamesFinder script in Assets/Scripts and Prefabs/Multiplayer Setup

    • No gif here, we believe in you 💪

Github branch link:

git clone https://github.com/moetsi/Unity-DOTS-Multiplayer-XR-Sample/ git checkout 'Creating-a-List'

Last updated