Getting Started with ECS in Unity 2019

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we're going to learn how to start working with ECS in unity 2019 we're going to cover what is EC s how it's different from game objects and then we will write a nice test to see the code in action and how ECS enables epic performance let's begin [Music] hello and welcome I'm your code monkey and this channel is all about helping you learn how to make your own games with nf2 torrents made by a professional indie game developer so if you find the video helpful consider subscribing okay so first of all ECS is one of the pillars of the new unity dot stack stack if you want to learn more about dots check the link in the description for the video where I go over what it is how it works and what are the benefits essentially dots is composed of the c-sharp chopped system the burst compiler and the entity component system the main difference when writing ECS code is switching from a object-oriented design into a data oriented design in the classical way of working with mana behaviors you have data and behavior in the same object whereas in ECS those two are separated you have components that simply home data systems that do work on that data and finally an entity which contains instances of component dan so with the theory out of the way let's get to writing some code first to get started trying out easiest you need to be using unity 2019 then go here into window and open up the package manager as of this recording the entities package is still in preview so you need to go into advanced and enable show preview packages then here scroll down and install the entities package related to that is the mathematics package this is a math library specific with performance in mind and finally the hybrid renderer package this is what we're going to use in order to render our entities other packages related to unity dots are down here the jobs package and up here the burst compound but for now we're just going to focus on simple ICS so all I need is the entities mathematics and hybrid render so with all of that we have all the components to start playing around with the entity component system alright so let's start off really small first let's make a normal script just to run our code so in here make a new c-sharp script let's call this just testing and let's add it to a game object so a new game object with testing and drag our script okay so here we can test our code now the simplest thing we can do is just create a new entity so for that first we need to go up here and make sure we are using unity entities and then we can test our code on private voice start and here to create an entity we need to use the entity manager so we grab it from the world that active dot entity manager this is the class that manages all of the entities then we can simply go into the entity manager and we just call create entity and just like that we have created a simple entity so let's run the code and see okay our code is running now all we did was create an empty entity there is no renderer or anything attached to it so obviously there's nothing to see here however we can go into window into analysis and the entity debugger so here is the entity debugger and here indeed you can see we have an entity all right so that's our first step creating a simple entity now let's go into the second part of ECS which is adding components so let's make a simple component let's say that we want this entity to have a 11 like in an RPG so we want to make a new component in order to hold that level so in here we make an EU c-sharp script let's call this the unlevel component and then here let's get rid of the normal mono behavior code and instead we're going to be using unity that entities and here we extend a component that this would we need in order to be able to use this as a component another difference is components are always structs so this is not a class 4 rather than a struts and now in here we just had all the fields that we want so in this case for our level let's just add a public hold for the current level alright so that's pretty much it for our component again remember components only hold data they don't have any behavior so now we can go back into our testing class and in here when we create an entity you can see that we can pass in a array of component types so in this case we pass in the component of type level components so just like that our entity won't be created with a level component so let's see so here we are the code is running and on the entity debugger we can click on the entity and here in the inspector you can see that it does indeed contain a level component ok so far so good now back in the code let's say we want this unit to start off at level 10 so for that we use the entity manager in order to set the component data then we need a reference to our entity so let's grab it here and we set the component data on that entity and for the component data let's pass in a new model component and we're going to start them off at level equals 10 so we are telling the entity manager to set the component data of this type with these values so let's s and we should be able to see our entity with level 10 and he appears the entity debugger and our entity 0 is indeed on level 10 ok so far so good so we can create an entity and add a component onto it now let's look into the unless part of ecs which are these systems in order to make a system all we need to do is create a class that extends the component system so let's make an EVC sharp script this won't be our level up system and in here again get rid of the mono behavior code and for a system we extend component system as you can see there is an error because we need to implement the on update method so this function will be called on every update and now in here we want to increase the level for every entity that has the unlevel component so to do that we do entities and we do a for each and here we pass in an action with the components that we're looking for so in this case we want our plugin component the ref parameter means this is a reference so we won't be able to modify the level component that so in here the code won't run on every with this particular component so in this case let's just increase the level like we would any other variable so we go into the level component and increase in level by own let's say one level per second so 1 multiplied by time.deltatime okay so we should be able to increase the level by 1 per second also the code in here is running on the main thread so that means that we can use debug block so for example derivative of that one of the unwelcome component that level and that's pretty much it for making a system we don't have to go back into our main class to add anything all we need to do is make it a component system and with that it won't automatically run so let's run the code and see ok the code is running and on the entity debugger we have our entity 0 and these areas you can see the unlevel component level is indeed increasing and here on the console we can see that it is indeed increasing ok awesome so we can create entities at components set their stiring data and we can also make systems that modify that component data so hopefully this example has been simple enough to follow along so far now let's look into a couple more essential basic things and then we'll work on actually adding a visual to our entity so first here in our testing class we are creating an entity and passing in a level component now let's say we want to add a second component we could do that by adding simply another type of and passing the type of the second component however the better way to create an entity with specific types of components is to create what is called an entity archetype so an archetype is essentially a specific set of components so up here we can define an archetype that contains all the components that we want so we ask the entity manager to create a archetype then we pass in our component types in this case first the type of model component and for a second let's add the standard position component so that's the type of translation component the translation is inside the MT transforms you can inspect this premade component not to see that it's very simple it simply contains valley which is a float 3 and E 4 3 is essentially a vector 3 as you can see it's inside unity dot mathematics and simply has an X a Y and they said and that's it we just created an archetype containing the components level component and translation now we want to create an entity using this archetype and now we do is in here on create entity we passed in our art tank so we should be able to see a new entity being created with the unlevel component and the translation component let's see and here's our entity and it doesn't need have the unlevel component any translation component so as you can see if you want to make let's say a bullet or an enemy you would make an archetype for each different type and then instantiate that now one of the main benefits of ECS is getting massive performance so making just a single entity isn't very fun so instead let's make a bunch of them using the same archetype the create entity function has a variation that takes the archetype and then takes a native array of entities so we create an array and then that array gets filled with entities so it's great here a native array now in order to use the native array we need to be using unity collections so create a negative array to home entities entity Arang and here we instantiate the array let's pass in our size so for our size let's start off very simple so we just with two entities and then we pass in the allocator this won't depend on exactly what you want to use the entity array for so in this case we just want to use it to instantiate our entities and then we don't need the array so we use temp ok then we pass in the entity array into our create and key function and now this one no longer returns an entity so all of the created entities are now passed into this array so now we just need to cycle so we cycle and here we grab the entity which is on the entity array on index I and we instantiate it with a certain level so in here let's start off with a random level so we are now correctly initializing all of our entities and afterwards we need to make sure to dispose of our native array so empty array and we simply call this post all right so we should now be creating two entities using this archetype and each of them won't have a random level so we can see that they are different all right let's see here's the entity debugger and indeed you can see we have two entities and here you can see that they have different levels this one is on level 30 and this one on 26 okay awesome so as you can see this is how you create multiple entities now instead of just two let's try spawning a lot more since setup to spawn mm let's see and in the entity debugger you can see that we are indeed creating two thousand entities and all of them are increasing their own level and if we check out our stats you can see that our CPU isn't working very hard with regards to updating 2000 entities now obviously it would be nice to be able to actually see them so let's see how we can add rendering here in our testing class first of all let's go back to just one entity so we can easily make it and on the archetype we have an 11 component the translation component and I'm in here let's also add a type of render mesh component the render mesh is inside using unity dot render this is what we're going to use in order to render a mesh and nor to view it we also need to add the type of welcome to world component this is what the renderer uses in order to calculate how it should be visible okay so now that we have our archetype set up and here we need to set the component data for the render mesh now the render mesh is not a component but rather a shared component so we need to go into the entity manager and call set shared component that for the entity and then we test in the render mesh here is the definition for the render mesh as you can see we have a mesh a material and then a bunch of things so let's add if you want to be able to use a mesh in material so in here make a serialized field let's pass in a private mesh for our mesh another serialize filmed for a material let's drag them in the editor so for the mesh let's simply use the default quand and for the material let's create the material in here so a new material let's call this our sprite material for the shader and let's use the unlit transparent and let's pass in this zombie falling body texture okay and drag it onto our field there like that okay now back in the code for the render mesh let's pass in the mesh as our mesh any material as our material okay so that's pretty much it our entity should now be visible using the quad mesh and our zombie texture let's see any of there's our zombie being displayed on 0 0 and if we go into the entity debugger you can see that it does indeed have the render bounds run run around welcome to world the render mesh with our mesh in material and the translation which is his current position ok so here it is just sitting around now let's make him move so here we are already in tension with the translation component which contains the position as we saw so let's make a system that moves in so down here making you see sharp script this won't be our mover system and in here we're going to do very much the same thing we did with an 11 system so we need to implement component system and on our update let's do entity cycle through for each entity and let's grab the entities with the translation component so in here we have the code that won't be run on every entity that contains a translation component and here let's just modify the translation that value and we just modify the one alright that you do it so let's see for Assam B is indeed moving up any of there's our zombie and he is moving up okay great now let's make a move speed component so in you see sharp scripts this will be our move speed component then here again let's do the same thing we did on the eleven components so we simply create first of all this is a struct it implements I component data and for the move speed all we want is a totally quote for our movie speed now on our testing class let's add this to our archetype so we add the type of move speed component okay when we create entities let's set the move speed component data and let's spawn five entities and let's also spawned them on different positions somewhere let's set the component data for the translation component and here for their starting value let's put them on a random position okay so here we are initializing our entity first we add it with the eleven component and we set it on a random level then we add the move speed component and we pick a random move speed and then we also set the starting point of the translation component which is going to be his position so we just randomize on the X and the y okay so we should now have five entities now let's see how they're going to move so here on the mover system and here we want to run our code on entities that contain both the translation component and also the move speed component so every entity that contains both of these we're going to run now when we run this code we move it by the move speed and then let's just make him bounce when he hits the top of the screen okay so we move him according to the move speed on this entities move sweet component when it gets to the top he starts moving down when he gets to the bottom he starts moving up okay very simple so we should be able to see our zombie's going up and down let's see any of there we have our five zombies they go up they go down and everything is handled by components and systems and as you can see they are going at different speeds based on the move speed component that they contain so we can go into the entity debugger here we see all our five entities and on each of them you can see they have the eleven component movespeed component and they are moving the translation so you can see varies of them and they have various values all right so now that we have our zombies going up and down let's try spawning some more here in order to spawn more entities only takes is really modifying the size of this array so I have five if I change it to ten now all of a sudden we have ten entities and they all work exactly the same they all have the same components in the same systems acting on those components and here on these stats you can see how fast the code is running right now taking one millisecond so let's add a couple more so instead of ten let's add a thousand any appear we have a thousand entities and as you can see it's only taking six or seven milliseconds so let's try pushing it some more now let's put 10,000 and here we have 10,000 units and as you can see the framerate finally starts to go down by a little bit now there's one improvement that we can make as you can see none of our sprites are being badged so let's sort that in order to do that we just need to go into our material and enable GPU instancing so for that we could technically use the sprites default as you can see it has the enable GPU instancing however for some reason when we enable this as you can see these prices appear so it seems there are some issues with this sprite shader when using GPU instancing but another shader that works is to go into here use the in legacy shaders and use the transparent diffuse and just like that they are now being seen as you can see they are all being patched again remember we have 10000 independent units on the screen right now if we had ten thousand game objects our scene wouldn't be running at all now one thing that is related to ECS is the burst compound and in order to enable bursts using ECS it's a really simple we just go appear into jobs going to burst and all we have to do is take this so let's see this one is taking 15 milliseconds let's simply take this and see how fast it goes anywhere we go we went from 50 milliseconds to just 3 this is so good it's pretty much magic so with this let's see how far we can push it and here we have a hundred thousand entities all showing all moving around independently and our frame rate is still at 40 frames per second and on my task manager here you can see my CPU being used at 77% and my GPU also being used at 60% so in this video we just covered the entity component system now a big part of the massive performance yet is when you combine the empty component system with the burst compiler which as you saw and then with the job system as well so if we were using the entire data stack we could probably push this up to maybe 200,000 so subscribe to the channel for more upcoming ECS tutorials using the complete dot stack with the job system the birth compound just to see how much performance we can squeeze out of this new way of writing code so to summarize the whole in T component system the first thing you do is create an entity you create entities according to a certain archetype which is a group of components each entity then contains an instance of each component the components are very simple they just have fields and implement I component data and then you have systems which act upon the data on those components we define which entities we want to run on by defining the components that they must have and then this kill gets run on every single entity and modifies the instance of every component on that entity so I hope this video has helped you understand and get started working with ECS it might sound confusing at first but once the core concept clicks it's actually rather intuitive as always you can download the project files and utilities from in Tacoma com if you liked the video subscribe the channel for more unity tutorials post any questions you have in the comments and I'll do my best answer alright see you next time [Music]
Info
Channel: Code Monkey
Views: 205,483
Rating: undefined out of 5
Keywords: unity ecs, unity ecs tutorial, unity ecs 2019, unity tutorial ecs, ecs unity, unity ecs job system, ecs unity tutorial, unity dots, unity dots tutorial, unity dots ecs, unity pure ecs tutorial, unity pure ecs, unity dots demo, unity hybrid ecs tutorial, unity ecs example, unity 2019, unity 2019.1, code monkey, brackeys, unity tutorial, unity game tutorial, unity tutorial for beginners, unity 3d, unity 3d tutorials, unity tutorial 2d, unity2d, unity3d, unity
Id: ILfUuBLfzGI
Channel Id: undefined
Length: 22min 44sec (1364 seconds)
Published: Fri May 03 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.