Create a Unity ECS Project
Full workflows and code to set up an ECS project with the latest Unity Editor and compatible package versions

What you'll develop on this page

"Authored" game settings data in a converted Sub Scene appears in the Entity Debugger
Basic game settings will be configured in a GameObject in a Sub Scene and can be viewed in the "Entity Debugger" at runtime.

Project setup

    Install Unity Hub 2.4.2+ if you do not have it already
    Install Unity 2020.1.17f1 if you do not have it already
      Go to "Installs" on the left side of Unity Hub pop-up window
      Click "Add" and choose 2020.1.17f1
      Once 2020.1.17f1 is downloaded, click on the three vertical dots menu (kebab menu) in the top right corner to add platform modules depending on your development and target platforms (OSX/Linux/Windows)
      Include iOS Build Support if you plan on completing the AR Foundation section of this gitbook
    Go to "Projects" in Unity Hub and click the down arrow to the right of "New" in the top left corner of the window to select 2020.1.17f1 and create a new 3D project, "Asteroids 3D XR Multiplayer"

Packages setup

    Once you're in Unity, navigate to Package Manager from "Window"
    Within PackageManager find the little "gear" icon and select Advanced Project Settings
    Check the box next to Enable Preview Packages and also Show Dependencies at the bottom of the window
      This will allow you to view the preview packages that are included included in the package manifest
    Outside of the Unity Editor, navigate to your project folder (wherever you saved it locally) and open manifest.json (inside the Packages folder) with Visual Studio code or your choice of editor
      These are all the packages that are currently included in your project
    We are now going to manually add a new package, the Hybrid Rendering package
    Add the following line to the manifest somewhere between the curly braces and save:
    1
    "com.unity.rendering.hybrid": "0.11.0-preview.42",
    Copied!
Enable preview packages and dependencies then add hybrid renderer package
    When you click back into the Editor, Unity will notice the updated manifest and "pull" down the hybrid renderer package we added (you'll see the "Importing" window pop-up with a loading bar)
    If interested, read up to the "Hybrid Renderer" section in this blog post to learn what makes the Hybrid Renderer "hybrid"
      Read the whole blog post if you want to be an ECS master, it is a great post!
    Hybrid Renderer automatically pulls in ECS dependencies (everything you need for ECS)
    You can see the dependencies of the package if you navigate back to the PackageManager in the Editor and select the Hybrid Renderer
    A key dependency is Entities, which brings in even more additional dependencies
      Entities v0.17.0-preview.41
        Burst v1.4.1
        Properties v1.5.0-preview
        Serialization v1.5.0-preview
        Collections v0.15.0-preview.21
        Mathematics v1.2.1
        Asset Bundle v1.0.0
        Performance testing API v2.3.1-preview
        Mono Cecil v0.1.6-preview.2
        Jobs v0.8.0-preview.23
        Scriptable Build Pipeline v1.9.0
        Platform v0.10.0-preview.10
Overview of selecting Entities in the PackageManager
    Adding certain packages directly from the Package Manager window is no longer possible (explanation in this post)
    For the duration of this gitbook, we will almost exclusively be adding packages through the manifest
We now have an ECS project set up
    created a new project
    added hybrid renderer to the manifest

Sub Scene setup

First, some background:

Unity has no plans to sunset GameObject/MonoBehaviour functionality given how incredibly powerful and mature their workflows are. That's why Unity built tools and workflows for developers to support GameObject workflows while also utilizing DOTS (a sorta 2-in-1, you can use both!).
One such workflow is the use of "Sub Scenes." Unity gives you the ability to split your scene into several Sub Scenes, which you use to partition various GameObjects and Entities. When a Sub Scene window is open (a.k.a. 'editable'), it operates in "GameObject world." When a Sub Scene window is closed, it operates in "Entity-performant world" (so to speak).
How is this helpful? Here's an example: Visual artists can build GameObject assets in Sub Scenes, as long as they have the Sub Scene window open in Editor. When done editing, the visual artist closes the Sub Scene window, which triggers the conversion of these GameObjects into Entities. The Entities can be streamed in and out as needed. The conversion-to-entities allows for enormous environments (as demo'd in the Megacity walkthrough below). If all those entities had been game objects, it would absolutely destroy the performance of a normal authoring scene.
This is how it works: This conversion of GameObjects into Entities within a Sub Scene takes place either when (1) you hit Play in Editor while the Sub Scene is open at the time, or when (2) you close the Sub Scene from its Inspector.
The conversion process itself shouldn't take long at all, even for massive scale environments like the Megacity demo.
External resources, if interested:
Unity's Megacity walkthrough: https://www.youtube.com/watch?v=j4rWfPyf-hk Watch this if you want a general understanding of the benefits of Sub Scenes.
Unity's post about Sub Scene conversion workflows: https://forum.unity.com/threads/new-subscene-converttoentity-workflows.638785/ Read this if you want to be up to speed with the latest and greatest updates.
Procedural generation of Sub Scenes: https://forum.unity.com/threads/generate-sub-scenes-programmatically.868984/#post-6598072 Read this if you are hardcore.

Now let's implement:

    Right click on the Hierarchy window and choose "New Sub Scene" > "Empty Scene"
    Name this Scene "ConvertedSubScene"
      This will automatically create a new folder with the parent scene name
      This will also automatically create a new folder called "SceneDependencyCache" which is used by Unity to help load/unload Sub Scenes
    Select "ConvertedSubScene" in Hierarchy
    Check out the settings in the Inspector
      "Auto Load Scene" is selected true by default, which means this Sub Scene will automatically load its Entities when the scene is loaded
    Double click on "ConvertedSubScene" and hit the play button
      Notice there are no cameras in the Sub Scene so nothing renders
    Return to "SampleScene" and hit the play button
      Notice that the skybox renders because a camera is present
Adding a Sub Scene to the scene and naming it "ConvertedSubScene"
You can see how Unity is able to handle both GameObjects and Entities at runtime without adding a single Entity, Component, or System. The GameObject camera functions as expected even with a Sub Scene loaded into the scene.
    Navigate to "Window" > "Analysis" > "Entity Debugger"
      This window will be used to see the Entity, Components and Systems we are setting up
      Click the down arrow to the right of "Editor World" dropdown and set "Show Inactive Systems" to true
      Click through the 5 entities and notice how their components and values are shown in the Inspector
      Think of the current 5 entities as autogenerated Unity.Entities "boiler plate" for our current scene / SubScene setup
        If you do not have 5 entities it is likely because your ConvertedSubScene is open which means it has not converted its GameObjects into entities
          Navigate to the SampleScene, which closes the ConvertedSubScene
          Still not working? Try saving, then reimporting the ConvertedSubScene by clicking "Reimport" in Inspector when ConvertedSubScene is selected in the Hierarchy
Not seeing 5 entities?
If you don't see all 5 entities, it's likely because Unity has not fully re-loaded yet. Your ConvertedSubScene might still be open, which means it has not converted its GameObjects into entities. To fix this, navigate to the SampleScene, which closes the ConvertedSubScene.
Still not working?
1) Try reimporting:
Try hitting save, then reimporting the ConvertedSubScene by clicking "Reimport" in Inspector when ConvertedSubScene is selected in the Hierarchy.
2) Try unchecking the box next to ConvertedSubScene in Hierarchy:
This checkbox toggles whether the Sub Scene is open for editing.
Here There be Dragons:
The Unity Editor can sometimes freeze up on your when reimporting assets with the Entity Debugger open. It eventually clears, but the delay can be upwards of a minute.
Setting up the Entity Debugger
We now are able to navigate Entities, Systems, Archetypes and see their associated data in the Inspector.
We now have a Sub Scene loading into our scene
    We created a Sub Scene "ConvertedSubScene" in the Hierarchy
    Opened the Entity Debugger and set "Show Inactive Systems" to true

Initializing game settings

First, some background:

Conversion Workflow

To use Unity’s DOTS technology, you need to create entities, components and systems
The process that "converts" GameObjects (authoring data) and generates entities and components (runtime data) is called conversion.
    This process is the preferred way of authoring ECS data
    It is a fundamental part of DOTS, and not something temporary
    Conversion is only about data, there is no conversion process for code
The overall workflow looks like this:
    1.
    The Unity Editor is a user interface to work with authoring data
    2.
    The conversion from authoring data to runtime data happens in the Unity Editor
    3.
    The runtime (e.g. the game) should only ever have to deal with runtime data

Fundamental principles

Authoring data and runtime data are optimized for wildly different goals.
    Authoring data is optimized for flexibility
      Human understandability and editability
      Version control (mergeability, no duplication)
      Teamwork organization
    Runtime data is optimized for performance
      Cache efficiency
      Loading time and streaming
      Distribution size
A key observation is that nothing requires a 1:1 mapping between GameObjects and entities.
    A single GameObject can turn into a set of entities, e.g. procedural generation
    Multiple GameObjects can be aggregated into a single entity, e.g. LOD baking
    Some GameObjects might have no purpose at runtime, e.g. level editing markers
The same can be said about components. A conversion system can read from any amount of Unity components and add any amount of ECS components to any amount of entities.

Key concepts

All those concepts get explained in further detail in the rest of this document, but it's useful to introduce some vocabulary beforehand.
    Authoring scene A regular Unity scene, containing GameObjects, destined to be converted to runtime data.
    Sub Scene A simple GameObject component that references an authoring scene and will either load the authoring scene (when the SubScene is in edit mode), or stream in the converted entity scene (when the SubScene is closed).
    Entity scene The result of converting an authoring scene. Because entity scenes are the output of an asset import, they are stored in the Library folder. Entity scenes can be made of multiple sections, and each of those can be independently loaded.

🔑 Major Key Alert 🔑

It is worth the effort to read through the Conversion Workflow documentation and wrap your head around Authoring/Conversion as it is a key part of ECS development
Unity's Talk on conversion workflows: https://www.youtube.com/watch?v=TdlhTrq1oYk Watch this if you want a more in-depth explanation (and/or prefer videos).

Now let's implement:

    Create a new folder called "Scripts and Prefabs" in the "Assets" folder within the Project window
    Navigate to the "Scripts and Prefabs" folder, right click, choose "Create" > "ECS" > "Runtime Component Type", and name it "GameSettingsComponent"
    Copy the below code snippet into GameSettingsComponent.cs:
1
using Unity.Entities;
2
3
public struct GameSettingsComponent : IComponentData
4
{
5
public float asteroidVelocity;
6
public float playerForce;
7
public float bulletVelocity;
8
public int numAsteroids;
9
public int levelWidth;
10
public int levelHeight;
11
public int levelDepth;
12
}
Copied!
Make sure to first clear the file before pasting in this code snippet.
    Components cannot store data pre-runtime. So, to set game settings in the Editor ("authoring"), we will need to use the conversion workflow
      public float asteroidVelocity = 10f; (cannot set values in IComponentData)
Create Scripts and Prefabs folder and GameSettingsComponent.cs
    Navigate to "ConvertedSubScene" and create a new Empty GameObject named "GameSettings"
      This GameObject will hold a script that will allow us to "author" game settings in the Editor and have those values converted at runtime into the GameSettingsComponent
    In "Scripts and Prefabs", right click, choose "Create" > "ECS" > "Authoring Component Type", and create "SetGameSettingsSystem"
      "Authoring" will allow us to add data in the Editor before runtime
    SetGameSettingsSystem.cs
1
using Unity.Entities;
2
using Unity.Mathematics;
3
using UnityEngine;
4
5
public class SetGameSettingsSystem : UnityEngine.MonoBehaviour, IConvertGameObjectToEntity
6
{
7
public float asteroidVelocity = 10f;
8
public float playerForce = 50f;
9
public float bulletVelocity = 500f;
10
11
public int numAsteroids = 200;
12
public int levelWidth = 2048;
13
public int levelHeight = 2048;
14
public int levelDepth = 2048;
15
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
16
{
17
var settings = default(GameSettingsComponent);
18
19
settings.asteroidVelocity = asteroidVelocity;
20
settings.playerForce = playerForce;
21
settings.bulletVelocity = bulletVelocity;
22
23
settings.numAsteroids = numAsteroids;
24
settings.levelWidth = levelWidth;
25
settings.levelHeight = levelHeight;
26
settings.levelDepth = levelDepth;
27
dstManager.AddComponentData(entity, settings);
28
}
29
}
Copied!
    If you ever want to set data before runtime in the Editor ("authoring") and have it exist at runtime as Component data for ECS to use, you will use a conversion workflow similar to above:
        1.
        Create the IComponentData that you will need
        2.
        Create an IConvertGameObjectToEntity (also an Interface, link to Unity docs) with public fields that match IComponentData
        3.
        Within the IConvertGameObjectToEntity use Convert() to take the MonoBehaviour data and set it to a Component during the conversion process
      On the next page we show how to use [GenerateAuthoringComponent] to add IComponentData directly on GameObjects
    Click on the "GameSettings" object in the Hierarchy, then in the Inspector click "Add Component" and select SetGameSettingsSystem to add the MonoBehaviour to the GameObject
    Make sure it's added and then navigate back to "SampleScene"
Create the SetGameSettingsSystem and add it to GameSettings GameObject
    Select "ConvertedSubScene" from the Hierarchy (make sure it's selected) and then click "Reimport" in Inspector
    Navigate to the Entity Debugger window and notice a new Entity with a GameSettingsComponent
      The new Entity with a GameSettingComponent can also be seen via a new EntityArchetype, found on the right side of the Entity Debugger
        Selecting a Archetype (the list on the right) will filter the Entity list (the list in the middle) to only Entities that fit the Archetype (i.e. "matching entities")
    Nice! The Sub Scene has followed the Convert() process and we have added the GameSettingsComponent to the converted GameSettings GameObject
Find the Entity with the GameSettingsComponent in the Entity Debugger
Remember, the GameSettings GameObject in our ConvertedSubScene automatically gets converted because it is a GameObject in a Sub Scene.
Our SetGameSettingsSystem set on that GameObject has "Convert()" triggered when going through the conversion workflow, which:
    1.
    takes the new Entity (which used to be the GameSettings GameObject) and
    2.
    adds a GameSettingsComponent to it, then:
    3.
    sets the GameSettingsComponent data to the data set in the Editor
...which results in an Entity with a GameSettingsComponent. We will use this Entity in the next section.
We now have "authored" data on a GameObject that's been converted to Component data on an Entity
    We created GameSettingsComponent.cs as our IComponentData the ("C" in "ECS")
    We created SetGameSettingsSystem.cs which uses Unity's Sub Scene Conversion Workflow
    We created GameSettings GameObject in ConvertedSubScene and added SetGameSettings as a Component
    We navigated to the Entity Debugger to see that the new Entity and its GameSettingsComponent have been added to the Entity list
git clone https://github.com/moetsi/Unity-DOTS-Multiplayer-XR-Sample/ git checkout 'Setting-up-a-Project-for-ECS'
Last modified 10d ago