Unity DOTS support in Rider 2023.1
Rider has always been the most innovative script editor for Unity (and Unreal!) game development, and Rider 2023.1 is no different. As part of this release, we’ve added support for Unity’s new Data Oriented Tech Stack, more commonly known as DOTS.
We’ve got new file templates, Code Vision for DOTS types, generation for boilerplate code, and of course, inspections and quick fixes. Let’s take a look at how Rider can help you write and update your codebase to work in the new DOTS style!
Furthermore, we’ll be at GDC in San Francisco next week, so if you have any questions, feature requests, or you just fancy a demo and a bit of swag, please pop by the booth in the South Expo Hall for a chat! We’ll be talking about Rider for Unity, Unreal and Godot, as well as team tooling, with YouTrack for issue tracking and TeamCity for CI/CD to build and deploy your games.
What is DOTS?
Put simply, DOTS is a massive architectural change for Unity, moving from an object-oriented to a data-oriented design. Currently, Unity games are a hierarchy of objects containing attached components for location, position, 3D mesh/2D sprite, lighting, physics, custom script behaviour, etc. The current model is conceptually easy to understand but has problems squeezing out maximum performance with larger, more ambitious projects. Since game data is stored per object, the CPU has to visit each object in order to update it, wasting precious CPU cache on unrelated data.
In contrast, DOTS is data-oriented, restructuring your game into Entities, Components, and Systems. If you need to update the position of a vast number of vehicle entities, all of those positions are stored as a single contiguous vector of position components. A system can then run straight through this array updating all of the positions in a very CPU-friendly manner, as the CPU cache only contains position data.
There’s a lot more to this new tech stack, so please check out Unity’s site for more details.
Rider and DOTS
As ever with Rider, we’ve looked at the workflows you’ll have to follow as you work with DOTS. We’ve built tools that will guide you in the right direction, helping you build games faster, learn the steps you need to take, and get out of the way – allowing you to focus more on your game.
Let’s start nice and simple with some new File Templates, so you can quickly create a new system, component data, aspect, or job class. Of course, these templates are all fully customisable, so you can modify the defaults and share them with your team or create your own.
Once you’ve got a system, component data, or aspect class or struct in your project, Rider will add a new Code Vision link, identifying that the type is used by Unity, just like we do for standard
MonoBehaviour classes and event functions. Clicking this will provide context actions, such as navigating to the corresponding generated code for systems and aspects or generating baker code for components. More on that next!
DOTS is an exciting new technology. However, it is very different from the traditional Unity architecture, and we’re all used to the nice workflow in the Unity Editor, using game objects and component inspectors to edit the runtime data for your scenes. Fortunately, DOTS can fit into this workflow with “authoring” components – a
MonoBehaviour that the Unity Editor can show in the Inspector to edit data, and is then converted into DOTS component data through a process called “baking”.
To do this, we need to create an authoring
MonoBehaviour component, a component data struct, and then a baker class to map the data across. This sounds like a perfect scenario for code generation!
Rider has extensive support for generating baker code. You can generate a baker and component data from your MonoBehaviour authoring component, or you can work data first and create an authoring component and baker from component data.
Let’s say you’ve already got your authoring component – perhaps you’re looking to migrate existing components to DOTS. There’s nothing special about an authoring
MonoBehaviour – it’s just a
MonoBehaviour with data and no actual behaviour. Use Alt+Enter on the class name or inside the class body and select “Generate Baker and ComponentData script”. (You can also use the Generate menu from Alt+Enter.)
You’ll be shown a dialog where you can select which fields to use when generating the baker and component data. It can be useful to use the Group button to group fields by declaring type, so you can see what’s available in the current class.
Select the fields you want to generate a baker for, and then check out the options at the bottom of the dialog. You can create a new component data type or add to existing component data. And you can do the same with the baker class – create a new class that will be nested inside the
MonoBehaviour, or add to any suitable existing baker. Once you’ve selected your fields and options, click OK, and Rider will generate a baker class and a component data struct for you. They’re generated in the same file by default, and you can then use existing Rider functionality to move the types to their own files or to move to another namespace.
Alternatively, you can also work data-first – write your component data struct, fill it with fields, and then Alt+Enter (or Generate) and “Generate Baker and Authoring script”. Again, select the fields, and choose whether to create a new baker as a top-level class or a nested class, or to add the fields to an existing baker, which can be useful to keep the number of authoring scripts down, helping your level designers.
Generating Accessor Properties
Aspects are a useful way of grouping entity components to make them more convenient to work with, such as the built-in
TransformAspect for working with local and world transforms.
Since component data is stored in native memory, an aspect requires you to use the
RefRW<T> types to handle read-only and read-write access to the data. This adds an extra level of indirection to your calling code, which must use something like
aspect.ValueRO.Speed to access a component value.
However, you can create accessor properties in your aspect to access the data more conveniently, and Rider can automate this for you. Again, you can use the Generate menu or Alt+Enter on a field inside an aspect that’s a component data type. Select the “Generate accessor properties” menu item, choose the component data fields, and Rider will generate read-only or read-write properties to simplify accessing the data.
Rider wouldn’t be Rider without some inspections! DOTS has a few rules that need to be followed, and Rider has added some inspections and quick fixes to help keep you on track.
Firstly, Rider will make sure that any call to
GetSingleton<T> in your system’s
OnUpdate method has a corresponding
RequireForUpdate<T> call in your
OnCreate method. If it’s missing, Rider will warn you, and a simple Alt+Enter will add it for you.
Similarly, if you’re using a
ComponentLookup<T> in your system, Rider will make sure you’ve called
Update inside your
OnUpdate method. Again, a quick Alt+Enter will add the call if it’s missing.
Finally, Rider will ensure that your component, aspect, and system types are properly declared, with warnings for missing
struct keywords, where applicable. If any of these are missing, Unity’s source generators will not generate anything for these types, and your systems and game won’t work!
Download Rider Now!
We hope introducing DOTS support in Rider 2023.1 will help you with this new way of working with Unity projects. And we’re just getting started! We’ll be adding more DOTS support in future versions, and if there’s anything you’d like to see, please let us know.
In the meantime, please download Rider 2023.1 today (currently in EAP, but we’re getting close to release!) and make sure to try it with your own DOTS projects.
And we look forward to seeing some of you at GDC next week!
Subscribe to Blog updates
Boost Code Quality with Qodana and GitHub Actions
It’s been roughly half a year since we introduced Qodana to .NET in our blog post about how to elevate your C# code quality with Qodana. Since then, we’ve been quite busy! Qodana went out of preview and into GA. Furthermore, we greatly improved the integration with our IDEs, providing an effortless …
Rider 2024.1 EAP 6: Updated New Project Dialog, Custom Naming Rules, and VCS Improvements
The latest installment in the Rider 2024.1 Early Access Program has just been released, and it’s jam-packed with updates. Before you download it, let’s take a look at the major changes. Updated New Project dialog To help reduce your cognitive load as you configure new projects, we have thor…
ReSharper 2024.1 EAP 6: The Most Feature-Rich Update Yet
The latest installment in the Early Access Program for ReSharper 2024.1 has just been released, and it's jam-packed with exciting updates. Let’s take a look at some of the highlights: Performance Faster Rename refactoring Renaming elements in your code is now faster and more efficient. T…