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.
Finished Project - Shooting down AR player from desktop
Finished Project - Getting shot down by desktop player
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.
Navigating between scenes using UI and appropriately handling creating/destroying client/server worlds
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 juicygame 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:
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()