Hello everyone!
We know that starting a project with functional samples can help users better understand and utilize Unity’s systems, including UI Toolkit. Internally, we frequently create test projects with example UI to explore and validate our tools, and we’d like to start releasing some of these as samples.
To start that process, we’d like to get your feedback on a preliminary sample: a minimap (made in UI Toolkit, of course!). While we have some ideas on how we want to turn this into a fully fledged sample, your input will help us shape them into the most useful resources possible.
Let’s get started–
You will find the project attached in a .zip file at the bottom of the post to explore!
For this particular UI project, we wanted to showcase a minimap with the following features:
- Reflecting the worldspace locations of certain game objects on the map
- Creating a flexible system that automatically adds and removes markers as needed
- Zoom functionality
- Clamping markers to the edges of the map
- Locked to “north” and rotating minimap functionality
And we accomplished our goal!
Here’s a breakdown on how:
-
Scenes
- We have just one scene called
Minimap
- In this scene you will find: the minimap UI, a basic environment, a player character, and some AI players that walk around on a NavMesh.
- We have just one scene called
-
UXMLs
- Most of the minimap UI lives in
Minimap.uxml
. This UXML includes the minimap itself, as well as the player marker and zooming instructions. It also includes a visual element calledMarkerContainer
that the other markers are added to at runtime. - It’s also worth noting that the only texture used in this UI is the render texture used as the minimap background–every other visual asset has been created right in the UI Builder using the exposed USS properties on VisualElements!
- The scaling mode for the background texture is set to
scale-and-crop
so that no matter the aspect ratio of the map, the render texture remains unstretched:
- Most of the minimap UI lives in
-
Each marker other than the player has a dedicated UXML template. These markers have their position offset by half of their size in order to center their origin points (aka their pivot points). We do this to account for VisualElements using the top left corner as their origin point by default.
-
Stylesheets
- The look of the UI is driven with selectors in
StyleSheet.uss
. The stylesheet is simple with a few selectors to customize the visuals of the different markers, as well as the the minimap itself
- The look of the UI is driven with selectors in
-
Components
- There are three main components for the minimap UI:
- The UIDocument component
- A script called
MinimapManager
(this is where all of the logic for updating marker positions at runtime is handled) - And a
MinimapMarker
script that is on every game object in the scene that needs a minimap marker
- There are three main components for the minimap UI:
-
Systems: How the minimap handles marker updates and zooming
-
MinimapManager
script:- The
MinimapManager
handles most of the minimap system–it sets up UI references, sets the rotation of the player marker, updates the positions of the other markers, handles live reload of UI, and ingests inputs to zoom the minimap in and out. It also has add and remove marker methods to be called by objects with aMinimapMarker
script attached to them. - Notes about the
MinimapManager
:- Unity camera viewport coordinates and UITK coordinates do NOT match up
- To correctly position our markers on the map, we used the helper method
WorldToViewportPoint()
- Important distinctions between screen space and viewport space:
- Screen space is in pixels so your coordinates would be between 0 and your game window’s resolution, i.e. x goes from 0 to 1920, y from 0 to 1080) whereas viewport space is always normalized to be between 0 and 1
- Also, screen space doesn’t account for where the minimap camera is being drawn on the screen (in our case the top left) and thus you would need to manually calculate how to get all of your markers to draw properly within your minimap on screen
- But, viewport space will always be relative to the camera’s viewport, so because we’re rendering it to a small render texture drawn in the upper left hand corner, we know our markers will always be placed there. If we move the minimap around, the markers will follow.
- This crucially also means that the system inherently handles minimap rotation–if we rotate the camera, the markers will still be in the correct positions because they’re still just relative to the viewport of the camera
- The
-
MinimapMarker
script:- Any game object with this component will get the minimap marker associated with it. This component also handles calling a
MinimapManager
method to add or remove markers on Start and OnDestroy.
- Any game object with this component will get the minimap marker associated with it. This component also handles calling a
-
MinimapCam
script- Gets reference to the player’s transform and sets the camera’s location (and rotation, if map rotation is enabled) to match it on Update
-
-
The project also contains scripts related to the player character (we used our Unity Starter Assets), the AI players, and a few other things that are not related to UI, and won’t be covered here.
So in the end, this project contains implementations of these UI Toolkit concepts:
- Moving UI elements to match GameObject transforms at runtime
- Dynamically adding and removing UI elements at runtime
- UXML Templates
- Live reload of UI Toolkit (enabling you to edit your UXMLs in playmode)
- UI visuals driven by stylesheets
And here were some of the benefits of using UI Toolkit to build the sample:
- Vector graphics (if creating assets solely in UITK)
- Customizable with USS and variables, making implementing multiple themes (such as a light and dark, or different aesthetics completely) very easy
- Also by implementing it directly in UITK rather than with a custom shader/sprite solution, it’s very easy to reuse existing UI theming on minimap, making implementation and matching visuals straightforward
- Easy text support (including localization, again helpful for tooltips, buttons, etc.)
- Built in mouse over / click events (could be useful for tooltips, leaving markers / clicking on buttons on the map)
However, a project alone does not a sample make, so we have some directed questions to start gathering feedback:
-
What would you like to see explained about the UI in this project?
- Insights on UXMLs & Stylesheets?
- Insights on the code / implementation?
- Notable hurdles and solutions?
- Limitations?
-
How would you like to access these explanations?
- Blog post on the Unity website?
- Further forum posts?
- In our UI Toolkit Documentation?
- In-editor tutorials?
- combo of the above?
-
How do you feel about the amount of UI included in this project? Too simple? Too complex? Anything you feel is missing?
-
Would you rather see us updating these samples to keep them relevant over time? If so for how long?
-
Or, should we instead focus our efforts on creating new samples covering multiple areas of UI Toolkit?
-
Lastly, we did NOT use data bindings for this particular UI implementation. Would you prefer an example that uses data bindings?
And of course, we are grateful to receive any other feedback as well.
Thank you for your time! And again, you can find the project attached to this post below. We are excited to deliver valuable resources for all of you using UI Toolkit, and we greatly appreciate your insight and feedback.
We look forward to your responses!
UIToolkit_Minimap.zip (9.9 MB)