{"id":332711,"date":"2023-03-16T11:42:48","date_gmt":"2023-03-16T10:42:48","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=dotnet&#038;p=332711"},"modified":"2026-05-04T13:58:20","modified_gmt":"2026-05-04T12:58:20","slug":"unity-dots-support-in-rider-2023-1","status":"publish","type":"dotnet","link":"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2023\/03\/16\/unity-dots-support-in-rider-2023-1","title":{"rendered":"Unity DOTS support in Rider 2023.1"},"content":{"rendered":"\n<p>Rider has always been <strong>the most innovative script editor for Unity<\/strong> (and Unreal!) game development, and Rider 2023.1 is no different. As part of this release, we\u2019ve added support for Unity\u2019s new <a href=\"https:\/\/unity.com\/dots\" target=\"_blank\" rel=\"noopener\">Data Oriented Tech Stack<\/a>, more commonly known as DOTS.<\/p>\n\n\n\n<p>We\u2019ve got new file templates, Code Vision for DOTS types, generation for boilerplate code, and of course, inspections and quick fixes. Let&#8217;s take a look at how Rider can help you write and update your codebase to work in the new DOTS style!<\/p>\n\n\n\n<p><iframe loading=\"lazy\" width=\"800\" height=\"450\" src=\"https:\/\/www.youtube.com\/embed\/2niCN6cDYQI\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"><\/iframe><\/p>\n\n\n\n<p>Furthermore, <a href=\"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2023\/03\/13\/meet-jetbrains-at-gdc-2023\">we&#8217;ll be at GDC in San Francisco next week<\/a>, 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&#8217;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. <\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">What is DOTS?<\/h2>\n\n\n\n<p>Put simply, DOTS is a <strong>massive architectural change for Unity<\/strong>, 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.<\/p>\n\n\n\n<p>In contrast, DOTS is data-oriented, restructuring your game into <strong>Entities, Components, and Systems<\/strong>. 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.<\/p>\n\n\n\n<p>There\u2019s a lot more to this new tech stack, so please check out <a href=\"https:\/\/unity.com\/dots\" target=\"_blank\" rel=\"noopener\">Unity\u2019s site for more details<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Rider and DOTS<\/h2>\n\n\n\n<p>As ever with Rider, we\u2019ve looked at the workflows you\u2019ll have to follow as you work with DOTS. We&#8217;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 \u2013 allowing you to <strong>focus more on your game<\/strong>.<\/p>\n\n\n\n<p>Let\u2019s 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, <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/Using_File_and_Code_Templates.html\" target=\"_blank\" rel=\"noopener\">these templates are all fully customisable<\/a>, so you can modify the defaults and share them with your team or create your own.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"720\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/file_templates1.png\" alt=\"Rider showing the &quot;New&quot; popup menu now with a DOTS section to create DOTS related scripts\" class=\"wp-image-332731\"\/><\/figure>\n\n\n\n<p>Once you\u2019ve got a system, component data, or aspect class or struct in your project, Rider will add a new <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/Code_Vision.html\" target=\"_blank\" rel=\"noopener\">Code Vision<\/a> link, identifying that the type is used by Unity, just like we do for standard <code>MonoBehaviour<\/code> 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!<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"700\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/code_vision.png\" alt=\"Rider showing a newly created DOTS system, with a DOTS code vision link and a menu to show generated code\" class=\"wp-image-332742\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Code Generation<\/h2>\n\n\n\n<p>DOTS is an exciting new technology. However, it is very different from the traditional Unity architecture, and we\u2019re 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 \u201c<em>authoring<\/em>\u201d components \u2013 a <code>MonoBehaviour<\/code> that the Unity Editor can show in the Inspector to edit data, and is then converted into DOTS component data through a process called \u201c<em>baking<\/em>\u201d.<\/p>\n\n\n\n<p>To do this, we need to create an authoring <code>MonoBehaviour<\/code> component, a component data struct, and then a baker class to map the data across. This sounds like a perfect scenario for <strong>code generation<\/strong>!<\/p>\n\n\n\n<p>Rider has extensive support for generating baker code. You can <strong>generate a baker and component data<\/strong> from your MonoBehaviour authoring component, or you can work data first and <strong>create an authoring component and baker<\/strong> from component data.<\/p>\n\n\n\n<p>Let\u2019s say you\u2019ve already got your authoring component \u2013 perhaps you\u2019re looking to migrate existing components to DOTS. There\u2019s nothing special about an authoring <code>MonoBehaviour<\/code> \u2013 it\u2019s just a <code>MonoBehaviour<\/code> with data and no actual behaviour. Use <em>Alt+Enter<\/em> on the class name or inside the class body and select \u201cGenerate Baker and ComponentData script\u201d. (You can also use the Generate menu from <em>Alt+Enter<\/em>.)<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"800\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/generate_baker.png\" alt=\"Alt+Enter menu showing Generate Baker and ComponentData option\" class=\"wp-image-332753\"\/><\/figure>\n\n\n\n<p>You\u2019ll 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\u2019s available in the current class.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1080\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/generate_baker_dialog.png\" alt=\"The Generate dialog used to configure generating a component data instance, with important fields selected from the authoring MonoBehaviour\" class=\"wp-image-332764\"\/><\/figure>\n\n\n\n<p>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 \u2013 create a new class that will be nested inside the <code>MonoBehaviour<\/code>, or add to any suitable existing baker. Once you\u2019ve selected your fields and options, click OK, and Rider will generate a baker class and a component data struct for you. They\u2019re generated in the same file by default, and you can then use existing Rider functionality to <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/Refactorings__Move__Type_to_Another_File.html\" target=\"_blank\" rel=\"noopener\">move the types to their own files<\/a> or to <a href=\"https:\/\/www.jetbrains.com\/help\/rider\/Refactorings__Move__Type_to_Another_Namespace.html\" target=\"_blank\" rel=\"noopener\">move to another namespace<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"800\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/generated_baker.png\" alt=\"A baker class and a component data struct generated by Rider from an authoring MonoBehaviour\" class=\"wp-image-332775\"\/><\/figure>\n\n\n\n<p>Alternatively, you can also work data-first \u2013 write your component data struct, fill it with fields, and then <em>Alt+Enter<\/em> (or Generate) and \u201cGenerate Baker and Authoring script\u201d. 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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Generating Accessor Properties<\/h2>\n\n\n\n<p><em>Aspects<\/em> are a useful way of grouping entity components to make them more convenient to work with, such as the built-in <code>TransformAspect<\/code> for working with local and world transforms.<\/p>\n\n\n\n<p>Since component data is stored in native memory, an aspect requires you to use the <code>RefRO&lt;T&gt;<\/code> and <code>RefRW&lt;T&gt;<\/code> types to handle read-only and read-write access to the data. This adds an <strong>extra level of indirection<\/strong> to your calling code, which must use something like <code>aspect.ValueRO.Speed<\/code> to access a component value.<\/p>\n\n\n\n<p>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 <em>Alt+Enter<\/em> on a field inside an aspect that\u2019s a component data type. Select the \u201cGenerate accessor properties\u201d menu item, choose the component data fields, and Rider <strong>will generate read-only or read-write properties<\/strong> to simplify accessing the data.<\/p>\n\n\n\n<img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/accessor_properties_preview.png\" alt=\"Rider generating an accessor property for a reference field in an aspect class\" width=\"800px\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/accessor_properties.gif\">\n\n\n\n<h2 class=\"wp-block-heading\">Inspections<\/h2>\n\n\n\n<p>Rider wouldn\u2019t 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.<\/p>\n\n\n\n<p>Firstly, Rider will make sure that any call to <code>GetSingleton&lt;T&gt;<\/code> in your system\u2019s <code>OnUpdate<\/code> method has a corresponding <code>RequireForUpdate&lt;T&gt;<\/code> call in your <code>OnCreate<\/code> method. If it\u2019s missing, Rider will warn you, and a simple <em>Alt+Enter<\/em> will add it for you.<\/p>\n\n\n\n<p>Similarly, if you\u2019re using a <code>ComponentLookup&lt;T&gt;<\/code> in your system, Rider will make sure you\u2019ve called <code>Update<\/code> inside your <code>OnUpdate<\/code> method. Again, a quick <em>Alt+Enter<\/em> will add the call if it\u2019s missing.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"800\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/missing_update_inspection.png\" alt=\"Rider showing an inspection for a ComponentLookup with a missing update call\" class=\"wp-image-332786\"\/><\/figure>\n\n\n\n<p>Finally, Rider will ensure that your component, aspect, and system types are properly declared, with warnings for missing <code>partial<\/code>, <code>readonly<\/code>, or <code>struct<\/code> keywords, where applicable. If any of these are missing, Unity\u2019s source generators <strong>will not generate anything<\/strong> for these types, and your systems and game won\u2019t work!<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Download Rider Now!<\/h2>\n\n\n\n<p>We hope introducing DOTS support in Rider 2023.1 will help you with this new way of working with Unity projects. And we\u2019re just getting started! We\u2019ll be adding more DOTS support in future versions, and if there\u2019s anything you\u2019d like to see, please let us know.<\/p>\n\n\n\n<p>In the meantime, please <a href=\"https:\/\/www.jetbrains.com\/rider\/nextversion\/\" target=\"_blank\" rel=\"noopener\">download Rider 2023.1 today<\/a> (currently in EAP, but we&#8217;re getting close to release!) and make sure to try it with your own DOTS projects.<\/p>\n\n\n\n<p>And we look forward to seeing some of you at GDC next week!<\/p>\n","protected":false},"author":96,"featured_media":333138,"comment_status":"closed","ping_status":"closed","template":"","categories":[4992],"tags":[8078,9105,7186,1978,1941],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/332711"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/types\/dotnet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/users\/96"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/comments?post=332711"}],"version-history":[{"count":9,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/332711\/revisions"}],"predecessor-version":[{"id":704869,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/332711\/revisions\/704869"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media\/333138"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media?parent=332711"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/categories?post=332711"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/tags?post=332711"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/cross-post-tag?post=332711"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}