What is the Purpose of this DOTS Tutorial?
This is a sample project that demonstrates how to create a multiplayer AR experience using Unity's DOTS. We include full workflows, code, GIFs and also share links to external resources.


Purpose
At Moetsi we build Reality Modeling technologies for Mixed Reality experiences. By Reality Modeling we mean the process of: capturing the spatial map of a real space, modeling the state of the environment, the objects within it, and the positioning of the sensors, and then packaging all that data for end-users.
A lot of our use-cases require both desktop and "live" (AR) client networking because part of what our technology does is stream updated Reality Models in real-time to connected clients, which is data-intensive.
We choose Unity DOTS and DOTS NetCode for our interaction layer. DOTS is able to handle heavy data processing without draining device batteries. DOTS NetCode uses an authoritative server model that works best for Reality Modeling.
Unity DOTS is still in the beginning of its development and as such, it goes through major iterations. Sometimes there are breaking changes in newly released versions of DOTS. We know this is frustrating, so to help out the developer community, the Moetsi team does its very best to keep up with DOTS' evolution and its interdependencies across Unity's technology stack. There are not too many DOTS tutorial resources online, which means there are probably a lot of developers going through the same (painful) process of trying to figure it all out. Resources on how to connect GameObject (Monobehaviour) Unity and ECS Unity (hybrid development) seems to be especially lacking for things like UI Toolkit and UI Builder. Hopefully Moetsi fills a void for you and the rest of the dev community!
We provide a tutorial and sample project for how to create a multiplayer real-time XR experience using Unity's DOTS. Anyone that has been interested in trying out DOTS but are concerned about stability or package interoperability can use this tutorial knowing that "it will work."
In this gitbook, we build a project that can deploy to both desktop and ARKit platforms. Desktop players will be able to navigate using WASD keys and AR players will be able to navigate using their device movement.

Github repo: https://github.com/moetsi/Unity-DOTS-Multiplayer-XR-Sample
Our focus here is on how to put pieces together in Unity DOTS, not an explanation of what the pieces are. For in-depth explanations of "what" the technologies are, we provide links to great external resources throughout this gitbook; we encourage you to click on those to dive in and learn more!
The styling (GUI) in the builds of this sample project is very minimal on purpose. Our sample project is not meant to provide a how-to guide on how to make a juicy game because we do not want to cloud your understanding of the underlying architecture. That's why we exclude anything but basic example implementations. If you are underwhelmed by the styling of the Asteroids apps in this project, that is good. A lot of the other DOTS tutorial materials we found online added superfluous bells and whistles that made projects more interesting, but we found that they got in the way of our true understanding of the underlying architecture.
Code-alongs will take anywhere from 5 to 50 hours (depending on your skill level and time commitment to reading through each line) and they cover these Unity packages:
Entities v0.50
Sub Scenes and conversions
Setting components and variables during conversion
Using EntityManager to make structural changes
Using command buffers to make structural entity changes
Setting up command buffers to run parallel jobs with CreateCommandBuffer().AsParallelWriter()
Adding, setting, and removing components
Generating authoring components and IConvertGameObjectToEntity interfaces
Entity queries and .ForEach()
Setting local variables for entity queries
Scheduling a job with .Schedule()
Scheduling a parallel job with .ScheduleParallel()
Running on the main thread with .Run()
Combining job handles with JobHandle.CombineDependencies()
Create and destroy entities programmatically
Create and move entities based on user input
Create an entity from a prefab
Adding cameras to entities
Hybrid ECS
New Build Configuration system
Creating a base shared configuration
Sub-second "play" start
Physics v0.50
Unity DOTS Physics
Using FixedStepSimulationGroup for custom systems
Physics Body
Adjusting PhysicsVelocity programmatically
Physics Shape
Updating shape type to prefab
Physics Categories
Custom categories for collisions and interactions
Triggers on collisions
Changing stateless triggers to buffer of stateful triggers
Acting on triggers to change materials and destroy entities
NetCode v0.50.1-preview.19
Navigating multiple ECS Worlds
Creating a ECS NetworkConnectionEntity (NCE) on the client and server
Creating a socket connection using NetworkStreamReceiveSystem
Use GhostDistanceImportance component
Sending RPCs between server and client
Sending data with RPCs
Using InvokeExecute on receiving NCE to make updates
Loading a game on the client
Using NetworkStreamInGame component
Updating the CommandTargetComponent on a NetworkConnectionEntity
Setting targetEntity field to ICommandData buffer
Creating networked entities ("Ghosts")
Updating Supported Ghost Modes
Server-spawned entities
Sending client inputs with ICommandData
Predicted responses to ICommandData by using ClientSimulationSystemGroup.ServerTick
Responding to ICommandData on both the client and server using GhostPredictionSystemGroup.ShouldPredict()
Client-predicted entities and predicted-spawned entities
Adding PredictedGhostSpawnRequestComponent
Ghost classification systems
Traversing GhostSpawnBuffer to locate predicted spawn entity
Proper NetCode entity destruction
Server-side destruction
Using ISystemStateComponent component as a call back to clean up destroyed players
UI Builder v1.0-preview.18 and UI Toolkit v1.0
Data binding
Creating a UI document and Panel settings
Creating a ScreenManager to handle switching between views
Nesting uxmls and custom Visual Elements in UI Builder
Creating custom VisualElements
Setting callbacks on OnGeometryChange()
Updating DisplayStyle to switch views
Creating a USS document shared by multiple UXML files
Creating a class list
Extracting inline styles to a class list
Adding classes to elements from StyleSheets
Creating custom styling for :hover and :active states
Styling a view to be responsive to changes in width to be prepared for both mobile and desktop views
Creating headers and footers for game information
Using display flex in UI builder to create responsive designs
Using standard Unity elements to create an interface
VisualElement
Label
TextField
Button
Adding a png or SVG background
Creating a ListView
Setting a source of data for the ListView
Creating custom click events and loading data when clicking on an item in ListView
Loading data in between scenes to configure host/client build
Using launch GameObjects to configure a scene to build as a host or a client
Creating a ClientServerBootstrap to stop automatic world creation
Triggering client and server worlds manually
Supporting Thin Clients when creating client worlds
Deleting all entities and worlds
Using UniversalQuery in EntityManager
Clean up to return to initial state
NetCode v0.50.1-preview.19, UDP Client, Broadcasting, Threads, Graceful exits
Using launch GameObjects to configure server and client connections
Triggering starting a game as a NetCode host
Triggering starting a game joining as a NetCode client to a specific IP address
Sending and receiving broadcast messages
Automatically sending a broadcast UDP packet of game information including IP address on LAN for players to join
Listening and receiving broadcast UDP packet information and populating a ListView of available LAN games
Running Threads for listening for UDP packets
Being able to run non-Unity handled threads in-game
Graceful handling of joining and leaving games
Adding NetworkStreamRequestDisconnect component on both host and client when quitting a game
Handling timeouts by querying for NetworkStreamDisconnected components from host and client to clean up entities and return to title screen
Server-authoritative score keeping
Creating PlayerScore ghosts and HighestScore ghosts to keep player scores authoritative and in sync
Associating scores with NCE NetworkIdComponent values
UI Toolkit + DOTS
Updating Game UI through a MonoBehaviour by pulling DOTS data from ghosts
Using GhostRelevancyMode to be mindful of network transmission
We will implement a server-side system that will send only send ghosts within a certain radius to players
We will also include overriding this behavior to send player scores to all players
AR Foundation v4.2.3
Setting up AR Foundation + ARKit plug-in
Adding AR Foundation GameObjects to game
AR Session Origin
AR Session
Dynamically checking if deployed to AR platform and disabling AR functionality if not
Creating AR-specific systems that only run when AR enabled
Grabbing Pose Driver value and providing it to ECS to move player
Updating input response systems for updated movement controls
Pulling ECS data spawn position and updating Pose Driver to move location of AR Camera to behind player
Use ARSessionOrigin.MakeContentAppearAt() to update origin of AR session based on game play
Dynamically updating UI for AR instructions when deployed to AR platform
Updating PanelSettings to be responsive to both desktop and mobile platforms
The UI Builder and UI Toolkit sections can be useful as standalone. However, all of the other sections build off one another so it is best to go page-by-page.
At Moetsi, we will always update our sample project to stay current with the latest set of working Unity packages.
Case in Point: in the middle of us writing this gitbook, DOTS was upgraded mid-project and we adjusted course to update our documentation and all of the packages as soon as possible.
This Sample Project is intended for developers who:
✅ already have a general understanding of Unity
✅ are looking for info on Entity, Jobs, Physics, NetCode, UI Builder, UI Toolkit, Multiplayer and AR Foundation packages
✅ are looking for a stable Monobehaviour / ECS hybrid solution template that is kept up to date with new releases
✅ are interested in building apps and/or experiences with high number of components/performance requirements (very often these are AR or other mixed reality apps, but don't need to be!)
This is NOT intended for those who:
❌ are looking for a full introduction to software development
❌ are looking for a "Pure ECS" solution
❌ are looking for a framework
Last updated