Unity ECS Roll-A-Ball - DOTS Tutorial 2020

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Hello All!

Recently I've been experimenting with DOTS - having a ton of fun, and learning a lot - so I figured I'd share some of the things I've learned so far. I decided to recreate the classic Unity Roll-A-Ball tutorial using DOTS and ECS to introduce people to the basic concepts of Entities, Components, and Systems and show how they all interact to do basic things.

In this video I'll demonstrate:

  • Converting GameObjects to entities
  • Spawning entities through code
  • Destroying entities through code
  • Rolling the ball entity with physics
  • Rotating the cube entities through code
  • Using the cubes as triggers so we can pick them up and increase our score
  • Making the camera GameObject follow the ball entity
  • And a few other useful tidbits along the way

I'm still pretty new to data oriented programming, so let me know if you think there is anything I can demonstrate or explain better. Open to any feedback on how I can make these instructional videos better for you all!

Also let me know what kinds of things you'd like to see in future videos related to Unity DOTS and ECS.

Enjoy!

👍︎︎ 5 👤︎︎ u/j_turbo 📅︎︎ Feb 06 2020 🗫︎ replies

That is a great idea, to introduce new ways to do stuff using an example familiar to everyone. Makes it much easier to understand how it was, and how it is done now.

👍︎︎ 3 👤︎︎ u/BanD1t 📅︎︎ Feb 07 2020 🗫︎ replies
Captions
hello everybody and welcome to a very special video where I'm going to be recreating the classic unity rollerball tutorial using the new entity component system which is a part of the data oriented technology stack so the entity component system is essentially a new way of programming games in unity where we separate out entities components and systems and we do this so we can get really high performance out of our games and I wanted to recreate the classic unity role of ball tutorials so I could introduce the entity component system to all in a nice easy way that's going to show you how to do many of the basic features in the entity component system also because we're using dots we can do some pretty cool things like this so in today's video I'm going to be going over entities components and systems and talking about how they all interact with each other then I'm going to be showing you how we can use traditional game objects and convert them to entities I'm also going to show you how to spawn entities through code and some of the systems that we're gonna be creating our show you had to roll the ball around the stage as well as making the cubes rotate also have you shown you how we can use the cubes as triggers so when we roll the ball into the cubes we can pick them up and increment our score we'll be showing you how we can destroy entities through code and then I'm going to be showing you how we can use our game object camera to actually follow the entity of the ball and be sure to reference any of the time codes down in the description if you just want to jump to a certain section in the video also down in the description you'll find links where you can download the completed project as well as the assets used to create this video and real quick I just like to say if you do find this video helpful make sure you leave a like also feel free to subscribe to the channel for lots more videos on the entity component system and the data oriented technology stack of course if you have any questions for me or suggestions for future videos feel free to leave those down in the comment section below so real quickly I'm just going to go over the entity component system so basically we just have entities components and systems so entities are just kind of representations of things in our game world so in this example this would be things like the ball the cubes and actually the stage geometry next we have components which actually hold the data associated with these entities so in this case we're going to be using some data which control how fast the ball moves as well as how fast the cubes rotate and finally we have systems and systems hold the logic that affects the entities in our scene so in this example we're going to be creating systems to actually move the ball around the stage as well as rotate the cubes and perform the trigger behavior when we actually run into the cube so we can pick it up and increment our score now real quickly I should mention that in this video we're not going to be using 100% ECS for everything because at the time of recording ECS is still in a preview phase and not everything has been you know moved over to the new entity component system so we're gonna have to do some things still in mana behaviors but I think that is an alright thing because you know when you go to make your game in ECS you probably will end up having to create some things with mana behaviors so I'm gonna be showing you how we can interact between entities and mana behaviors but anyways I think that's enough talk let's go ahead and get into the tutorial video so of course we're just gonna start the blank project here I'm using unity version 2019 that 3.0 and at the time of recording this is actually a preview version of unity anyways we're going to be importing the 3d templates here just go ahead and give it a project name of dots rollerball and save that to wherever you like alright so once we have unity loaded up we can go ahead and import a couple of preview packages so we'll just go up to window and package manager it'll go ahead and open the package manager here now the first thing you need to do is go to the Advanced tab here and make sure show preview packages is checkmark so it'll look just like that and then also make sure you're looking under the all packages here so we have to import three different preview packages the first one is going to be entities so just go ahead and click on that and click on install and go ahead and let that install and this is the package that's going to give us access to the actual entity component system itself alright and once that's complete the next package that we're going to need to import is the hybrid renderer so just go ahead and click on the hybrid render again click install and wait for that to install and this is gonna allow us to actually render the entities within our scene all right and then the last one that we're going to need access to is unity physics so we'll just go ahead and install that last one and of course this is gonna allow us to use the new physics system which integrates with the entity component system all right so once we have those three packages installed we can just go ahead and close out of the package manager and there's one more thing we need to set up in our editor we just want to go up to window here and then under the analysis section we're gonna open what's known as the entity debugger and then you'll see a little window pops up here I just like to put this right next to my console here so I can flip back and forth but this is gonna be the main kind of debugging window that we're gonna use when we start making entities and everything so we can actually see the entities themselves along with what components are associated with them and even the systems that are impacting those entities so this is a really helpful window to have so make sure we have that open all right so we're just gonna go ahead and create some basic scene geometry pretty standard unity stuff we're just gonna start with a 3d plane here we're gonna make this a 2 by 2 size and then we're gonna just put some walls on it and these are gonna be the dimensions that you're going to be putting on all the walls all right and then once we have that set up I'm just gonna go ahead and import some materials that I had here should go into the materials of this ground material just a nice simple blue material here just to kind of give it a little bit of color and then real quick just gonna change the angle on the camera here all right so this is looking pretty good so before we go any further I think we should just go ahead and save the scene or a quick I'm just gonna call this the roller scene all right so next we're gonna add some things to these basic geometry objects in our scene so just go ahead and highlight everything just the plane and the four walls here we're gonna go ahead and go to add component and then we're just gonna go ahead and add a rigidbody component and when we actually convert these game objects to entities the colliders are going to be converted into what are known as physics shapes and the rigid bodies are going to be converted into what are known as physics bodies and so actually if we want we can actually add in a physics body or physics shape if we want to but I just want to show that you can actually convert these rigid bodies and mesh colliders dynamically very quickly one thing we need to do on the rigid bodies so just go ahead and highlight all of them again we're gonna uncheck use gravity and then we're gonna check is kinematic because these are just kind of static objects in our scene that we don't want to be moving anywhere so now it's pretty easy how we actually convert these to game objects so we're just going to go ahead and add a component which is going to be the convert to entity component so click on that and the conversion mode is set to convert and destroy so what exactly does that mean well I'm gonna go ahead and show you now so see of course that we have these you know five objects showing up in our hierarchy here however when we go into the play mode things are gonna change a little bit so you'll notice that all those objects that we had they disappeared from our scene hierarchy and they're actually nowhere to be found in there however they still are showing it but our scene so they're not you know completely disappeared so where do they go well that's where we start getting into the entity debugger here so you'll see when we go into the entity we have all the entities listed here so we have the four walls and the plane and we can actually click on these here and we can see all the associated values showing up in the inspector just how we would with a normal game object and even further than it just listing all the components we can click on this worse as used by systems and it lists out all the systems that are associated with these different entities all right so because this is the role of ball tutorial the next thing that we're gonna add in is a ball for us to roll so again we'll just go up here and we'll just create a 3d object that is a sphere we'll just set the Y position to point five so it sits right on top of that plane nicely there and so what we're gonna do this time is we're actually gonna go ahead and remove the sphere Collider and we're gonna go ahead and add a physics shape which we can set to shape type of sphere and just go ahead and leave all the default values we're gonna add another component which is going to be a physics body and so because we're gonna be moving this around this is going to be a dynamic body and we can just go ahead and leave the rest of the defaults as is and lastly because we're going to be converting this to an entity we're gonna go ahead and add the convert to entity component to your make sure the conversion mode is set to convert and destroy and then I just have a ball material here which we're gonna go ahead and apply to it just this nice little basketball here so just a nice little thing that we can actually see when this ball is rotating so anyways real quick I'm actually just gonna raise this sphere off the ground temporarily so that you'll see when we go ahead and hit the play button here you'll see that it automatically starts to interact with the unities physics engine and then boom there you go gravity is working as expected and so of course if we wanted we could give this like a bounce material make it bounce off the floor but we're not going to do that for now so I'll just go ahead and put this back on the floor at a height of 0.5 all right so now we pretty much have our basic entities so now it's time to start adding some components to them and we're just gonna be starting with one component this is going to be a Speed component but we're gonna be adding to the ball here so we can kind of regulate how quickly the ball moves around alright so just in the assets folder here I'm gonna go ahead and create a new folder called its scripts and then under the scripts folder I'm actually going to create a couple new subfolders what it's going to be for our data components and then we're gonna have another folder for our systems and this just kind of separates things out make things a little bit more organized so anyways we're gonna start with a data component here so we're gonna go ahead and create a new C sharp script and I'm just gonna go ahead and call this speed data and then so we'll just go ahead and double click that to open up in our IDE of choice alright here we go time for the fun stuff here's some coding so we're just gonna go ahead and clear out everything in here because we don't need any of that so first we're just gonna start off by including a library so we're going to be using unity dot entities and so this is going to be a public struct and it's gonna be of type speed data of course and so this is actually going to inherit from an interface known as I come data all right so I'm just gonna go ahead and open close the curly braces here and then we just need one public variable which is going to be a float which is going to be our speed variable here and if we wanted we could add in you know more fields here like if we wanted some type of a counter we could have that in here however for this particular data component we just need this one speed variable and then the only other thing that we need to do in this script here is we're gonna add a tag so this is actually gonna be the generate authoring component tag and what's that is going to allow us to do when we save this and go back to unity once that all compiles we can just go ahead and drag the speed data component and go ahead and put it on our sphere here and we can see that we can actually edit this value so we can put you know whatever we want for the speed so for one two the speed of yeah ten we could put that in there for one of the speed of three thousand we could put that in there but I think ten is probably some something good to start with and so that's the basics of a data component it's very simple and straightforward so now things start to get a little bit more fun when we add in some systems so we're gonna go ahead and add our first system which is going to be the movement system which is gonna allow us to actually move the player ball here so in the system subfolder we're just gonna go ahead and create a new C sharp script and we're just call this our movement system and once we have that just double click to open alright so here we can just clear out the start and update functions and we're just clear out all the includes that we have here and these are the libraries that we're gonna be importing so it's unity densities unity dot jobs you need that physics unity dot mathematics and the unity engine the next thing we need to do here is instead of inheriting from monobehaviour are actually gonna be inheriting from the job component system you see that when we do that we're already getting a little bit of an error here so we just click on this and in Visual Studio it's really nice you can do alt enter and then hit enter one more time then it goes ahead and puts in this one needed function which we need when we inherit from this job component system here and so this on update function it's you know similar to the regular update function it's called every single frame and this is going to be where actually most of the work in the entity component system is done is within these on update functions so actually the first thing that we're going to do is we're gonna get a float variable which we're gonna be calling Delta time and then we'll set this equal to time Delta time and the reason we do this is because we're gonna be doing a lambda function in just a second here and who actually can't grab Delta time from inside that lambda function so we just need to do it outside like this so no big deal next we're gonna do a float to variable and a float to is basically it's similar to a vector - it just holds two floats but it's a little bit more lightweight and that is included with this unity mathematics library here and so we're just going to go ahead and call this the cur input and we're gonna set this equal to a new float to taking an input from the vertical and horizontal axes alright so once we have those two things we're going to be implementing our lambda function again start getting used to these because we're gonna be using them a whole bunch in ECS so the way we actually do this is we say entities dot for each so do open parenthesis another open parenthesis first we're going to be getting a reference to physics velocity and we just call that ve el vel then we're gonna say in speed data and then we'll just call this yeah speed data that's fine so what this means is it's going to iterate through all the entities that match these parameters here so we do entities dot for each and we pass in a reference to physics of velocity and then in for speed data so this basically is going to iterate through every entity that has a physics velocity as well as a speed data component associated with them now the ref is a reference meaning that we can read from as well as write to the physics velocity and because we're going to be you know actually moving the player we need to read what it is currently we're gonna make some modifications to it and then write to it so we can actually update its velocity which is going to actually move the ball and then the in keyword this is basically when we just need to read data from something so we're just going to be reading the speed data just to know how fast to actually move the player this isn't something that we need to modify so we just use the in keyword here alright so next after the first end parenthesis but before the second we're just going to go ahead and do an equal sign and then an make an arrow like that and then we're gonna do an open closed curly braces at the end we're going to do a semicolon and then we can actually put these braces kind of on their own lines here and separate this out so here's what we're actually going to be doing within this for each loop here so first we're gonna get another float to variable or new velocity we're gonna set that equal to ve l dot linear so this is its current linear velocity dot X Z so this is that's current linear velocity in the X and z directions we only care about X and Z because again this is just kind of moving on the 2d plane there so after that we're just going to go ahead and say new velocity plus equals cur input so whichever direction the you know players inputting so if we're inputting a forward or left or some kind of a diagonal direction we're gonna get that here we're gonna multiply that by our speed data dot speed so that's just the speed value that's attached to that speed data component and then of course we're just going to go ahead and multiply that by the Delta time that we captured and then the last thing that we need to do is just apply this new velocity back to the current velocity so it is Duvel that linear dot x z set that equal to the new velocity just like that and so now that we have the code here we just need to tell the job system to do a dot run so we'll make sure this is you know after that last parenthesis but before that semicolon that we put there and the dot run just means that we're going to be running this operation on the main thread and then after that you'll see that the on update function is still gives you an error all we need to do is just say return default and that's pretty much all set one thing that we do need to do is just right above here we're gonna add in a tag which is the always synchronized system tag and basically when we're running things on the main thread in ECS we just want to include that tag there so it syncs everything properly now we can head back to unity and let everything compile and then we can actually go ahead and test out our game alright so now that it's compiled we'll just go ahead and enter play mode here and then you'll see we can use the WASD Keys and we can start rolling the ball around so boom there we go we're already rolling the ball around for the unity rolling ball now you can already tell that things are quite different than traditional unity programming and you know we're gonna get into some some weird stuff here but hang on I promise it's not all that intimidating and can start to do some really really cool things and then real quickly well I'm kind of messing around in play mode I do want to point out one quick thing in the entity debugger here so you can see all the active systems listed here and you'll see that one of our systems is the movement system so we can actually uncheck that and if we go back over into here and pressing the WASD Keys but nothing is happening and that's because the system has actually been disabled however we can just rename that come back over here and just start moving again so again this can be pretty handy to start debugging things you can you know uncheck different systems that are running here to test out different parts of your code ok so now that we have the ball rolling around the next thing that we can do is start adding some cubes for the ball to pick up so again we're just gonna go ahead and go up here and we're going to go ahead and create a 3d cube and then I just have a basic little yellow material to apply to this and so again we'll just actually go ahead and remove the box Collider and we'll add in our physics body physics shape and convert to entity components now we're going to set these boxes as kinematic because we don't need them too you know mess with gravity or anything like that so we'll just go ahead and call this the pickup cube and so I'm gonna go ahead and make this cube a prefab so I'll do a little uh prefab folder here pickup cube in there and then we go go ahead and just duplicate out a couple of these here okay one thing that I forgot to do that we can just do on this main one here is we need to make this a trigger so in the physics shape there's an option for is trigger you just go ahead and check mark that and I'm gonna go ahead and apply this to the prefab and these all should be showing up as triggers and so this is gonna allow us to when the ball runs into it we can just activate a trigger and we can actually pick it up instead of you know colliding with it and maybe knocking it off into space or something which would be cool but that's not we're going for today so next thing that we want to do is we're actually going to be rotating these so of course we're going to need some sort of rotator system and of course it's gonna have some kind of speed of how quickly we want this to rotate and if you remember we actually already have a data component for our speed data so if we want we can actually just go ahead and apply this speed data right on to you know one of our cubes here make sure this of course applies to all of them and we can just go ahead and give this a speed of say five we can have them go ahead and rotate at five and then we'll just go ahead and apply that speed to all of them there now however what I just did there is incorrect and I'm gonna show you why right now if we go into play mode here obviously we haven't created our rotating system so they're not gonna start rotating so what's gonna happen is when I use the WASD Keys to roll around you see that whoa all the cubes start running around with the ball which again kind of funny but not what we're going for in today's today's game so now the reason that that happens is in our movement system here this is iterating this movement system on everything with a physics velocity component and a speed data component so not only does the ball have a physics velocity and speed data component but all these cubes do as well so luckily there's a pretty easy fix for that we can just go ahead and create a new data component here so just do a new c-sharp script just call this the rotation speed data and so we actually just go to our speed data component just go ahead and copy this and delete all that and paste it over make sure we just change the speed data to rotation speed data and again we can just have this public float called speed so we can save that over to unity and let that compile and we can actually just open up the cube prefab here we're gonna go ahead and remove the speed data component add on the rotation speed component and then put on a rotation speed of 5 so now you'll see that we can go ahead and roll around here and you'll see that the cubes all stay just in place and we can continue moving the ball around just as we would so now let's go ahead and actually implement this rotation system so we can get the cubes to rotate all cool like so we're just going to system's here and we're gonna go ahead and create a new C sharp script just going to be our rotation system and open that up of course we can blow away the update and start functions as well as these includes up here and so we're gonna be using these includes instead or so it's unity dot entities unity that jobs internet transforms and unity dot mathematics and of course again we're going to be inheriting from the job component system and so once again we're getting an error so we just click on this do alt enter and enter and so the rotation system is fairly straightforward again we're just going to want to do a float for Delta time so we get a reference to the time Delta time here do the lambda function again so entities for each this time we want a reference to anything with a rotation component we'll just call this rotation and we're just going to read from anything with the speed data and so we can just call this rotation speed ways of course we're gonna need to do this interesting little arrow thing and the brackets a little semicolon at the end make these lambda expressions all nice neat and then so basically what we're gonna do is just rotate it across the x y&z axis at the same speed it's just every single frame so pretty simple way we do that is we just do our rotation dot value so that's how we get the current rotation value and this is a quarter nyan so we need to kind of do some interesting little maths on here so do math dot mole passing in the current rotation value and we're going to do multiplying that with quaternion dot rotate x2 rotate this in the x direction here we're gonna be passing in math radians of our rotation speed speed multiplied by delta time so again this may be a bunch of weird mathematical things but pretty much we're just going to be rotating this around the x axis at the specified speed every single frame and so we can just copy this line here and paste it again paste it again and we're just gonna change this to rotate Y and rotate Z of course we're gonna be running this on the main thread so we'll just do a dot run at the end here and then once again return default and lastly we're just gonna go ahead and give this the always synchronized system tag here go ahead and save that back over to unity wait for it to compile all right and once it compiles we can just get a nice view here and then if all goes well when we hit play all our cubes should start rotating around all three axes boom there we go we see they're rotating a little bit slow so again we can you know kind of stop this go to one of these cubes we can increase the speed twenty-five lets me go pretty quick and apply the changes all right there we go and we have all our cubes rotating so they're kind of like intriguing for you as the player to you know one actually go and pick these things up so of course we can move around and we're just we're just going to be going right through them because they are set up as triggers so we're not colliding with them or anything like that so the next thing that we need to do is put some kind of logic behind them to say you know what happens when we actually enter one of these triggers here how are we gonna pick them up so the way we actually do this is a little bit interesting in ECS so the way that I'm gonna be showing you how to do this today is when we collide with one of these it triggers a trigger event when that trigger event happens we're going to apply a delete tag to the cube and then so at the you know near the end of the frame we're actually gonna run this operation the scans through all entities with a delete tag and if it has that delete tag it's actually going to delete the entity so it's it's kind of like an extra step you have to take instead of just saying you know when I collide it I delete it but that's just kind of how working with ECS is right now so first we're going to add another data component and this is just going to be a very very simple one and this is just gonna be called the delete tag it's not even delete tag data or anything like that it's just delete tag and you'll see why because we're pretty much putting nothing in here at all so just go ahead and clear all that out and just go to another one of our data components here copy that all over and paste it in again this is going to be the delete tag and we actually don't even need any variables at all so this is literally what our delete tag looks like basically it's just an empty component that again nearing the end of the frame when we actually scanned through everything with the delete tag anything that has this is gonna get deleted so this is pretty much all we need just completely empty super simple so before I show you how to be the pickup system because that one's going to be the most comp kated I'm gonna show you how to make the delete system because this one is pretty straightforward so we'll just do a new c-sharp script call this the delete entity system of course just clear all that out at the beginning and all that out there and this time we're just going to be using unity dot jobs you need got entities and then unity dot collections once again we're just going to be inheriting from the job component system and go ahead and implement this on update function here and so the first thing that we're gonna be using here is something known as the entity command buffer and we can just call this command buffer and we'll set this equal to a new entity command buffer and then passing in allocator dot temp job so basically this entity command buffer we can use this for a couple of different things and we're going to be using this in the pickup system and so pretty much we can kind of use this to queue up different jobs within a job and then at the end we can actually play through all those jobs and this entity command buffer it's gonna allow us to do some pretty cool things such as adding components to game objects which we're going to be doing course in the pickup script and in this case we're actually going to be using it to delete entities entirely so this time I'm going to show you a little bit of a different way to do lambda functions but it works just the same so we're going to do entities and we're going to go to a new line and then if you're tabbed over just like this we're gonna do a dot with all passing in the type of delete tag so this pretty much means it's gonna run on all the entities with the delete tag and then just do open and close parentheses there and then we're gonna do another line and then we're going to do a dot for each this is where we do our for each inside here we're going to do and entity or just call this entity and then here's kind of where we do this like we were doing before so then here all we're gonna do is go to command buffer and do a dot destroy entity and then we're just going to go ahead and pass in the entity which we're gonna called entity and so that basically kind of get this in the command buffer saying that when the command buffer runs this thing that we're gonna do is destroying an entity so if we said had like a bunch of things with this delete tag then of course we'd iterate through all of these and then we'd add this destroy entity passing in that entity to the command buffer once we have all those queued up then we can actually play through all those things in the command buffer which will actually go ahead and delete the entities so real quickly we just do a dot run here because we're gonna run this on the main thread so then after this we're going to do a command buffer dot playback and then we need to pass in an entity manager and we can just pass in entity manager just like that and then one thing that we need to do with this command buffer is just do a command buffer dot dispose and then so that just kind of like you know clears that out of all the memory because we don't need it anymore and then lastly of course we just need to go ahead and return default so anyways this was a little bit of a different way of setting up these lambda expressions we're going to actually come back to this script and we're actually gonna add like another element here you can see it we can just kind of do pretty much just like a newline and do a dot you know with all dot for each we're gonna add another little element to there in just a second but for now we can save this go back to unity and make sure everything's compiling without any errors so now we can go into play mode but nothing's gonna happen because nothing is actually getting this delete tag actually I can show you a quick we can just go ahead and put this delete tag on one of our cube prefabs here make sure we just apply those changes and then just kind of verify that everything yep has this delete tag but pretty much what's gonna happen is when we hit play it's just gonna delete all the cubes so play and boom all the cubes are gone just like that so we'll just go back to this prefab and we no longer need that delete tag go ahead and apply those changes so pretty much what's gonna happen now is we're going to use this pickup script for when we run into one of these cubes we're just gonna add the delete tag to it and it's going to go ahead and delete it so go back into the systems folder and we're gonna create a new C sharp script and this is going to be the pickup system again clear out the start and update this time around we're gonna be using unity entities unity dot collections unity that physics you need that physics that systems and unity dot jobs once again inheriting from the job component system and then of course we're going to need to add in the on update function here and so actually I'm just gonna leave this not implemented exception here because we're going to come back to this on update function so under this we're gonna go ahead and actually create a new private struct and we're gonna call this the trigger job and this is going to inherit from I trigger events job and then so again we can just do click on this do an alt enter and enter and you see that we need this execute method as part of this interface for the I trigger events pretty much what's gonna happen is anytime that a trigger event happens this execute method is going to be called so within here we can run some checks on the entities that actually through this job so then we can kind of determine which one is which and then apply of the delete tag to the cube and then we'll actually delete the cube and so you'll see if we go here and we do a peek definition on this trigger event you'll see that there is an entity pair called entities and on this entity pair called entities and then if we go peek the definition of the entity pair you'll see that there's an entity B and an entity a so essentially what this means is this trigger event we can access the two entities that are part of that trigger event so one's going to be the object and then one's gonna be the trigger we're gonna do just a regular if statement but before we put in that logic we actually need to set up a couple variables here so above the execute function within this struct here we're going to have a public component data from entity and it's gonna be of type speed data again this is the speed data component that's attached to our ball so we can call this speed entities so this is essentially what's known as a native array of all the speed entities within our scene next we're going to do a read only tag on a public component data from entity again and this time it's just the delete tag is what we're gonna do that on and so we can call this entities to delete then lastly we need a public entity command buffer and just call this our command buffer and again this is gonna allow us to add the deletion tag to certain entities in the execute function we're gonna say if Speed entities dot has component trigger event dot entities entity a so basically this is kind of a long way of saying if entity a of this trigger event has a component that is speed entities we know this basically means entity a is a ball because only balls have the speed entities component so if that's the case we're going to do another if check this time we're gonna check if entities to delete dot has component trigger event dot entities that entity B so we're gonna check if entity B already has a entities to delete component if it is then we don't need to add another delete tag to it so if that's the case we're just gonna go ahead and return here otherwise we're going to do a command buffer dot add component and we're gonna pass in the entity that we want to add the component to which in this case is going to be trigger event entities entity B and the component is going to be a new delete tag so again what's gonna happen is when one object collides with a trigger this trigger event is fired so first we're going to check if entity a has a component of speed data and so if it does then we know that that object is a ball and realistically after this it might be a good idea to check if entity B also has a component of that rotation data so we know that that other component is in fact a cube but however because this is a pretty simple thing and the only things that have triggers are cubes we can pretty much guarantee that it's a cube that were colliding with however we do want to check that cube so entity B which is the other thing we're going to check if that has component of the delete tag and if it does then we don't need to add another delete tag to it so we're just gonna return out of here but if it doesn't already have it then we're just going to do a command buffer that add component again passing in that entity B and then that delete tag so it'll add the delete tag to entity B so one thing you may have noticed is we actually don't know if entity a is going to be a trigger or if entity B is going to be our trigger so we have to check in both cases and we flip a and B each time and the easiest way I've found not to do this is just to create its own separate little function so I'm just gonna go ahead and implement that now real quick [Music] alright so pretty much what I've done here is I've separated out this test entity trigger function which just takes in entity variables for entity 1 and n 2 D 2 and then up here when I make the calls I do entity a than entity B then I call it again passing an entity B then entity a so basically it checks both cases so it doesn't matter if a is the trigger or B is the trigger we're gonna find it either way so now that's all well and good however we actually never you know schedule this trigger job to work so within the on update function here is we're actually gonna go ahead and implement that we're going to create a new trigger job and we'll just call this trigger job that's fine so this equal to a new trigger job and then within some brackets here here's where we actually set these three variables so we need to set the speed entities entities to delete and the command buffer so for Speed entities when we do that as we'll just type in speed entities and we'll set that equal to get component data from entity passing in speed data so again this is just going to return an array with all the entities with a speed data component so we'll do a comma at the end and then do the next variable which is the entities to delete so again we're gonna set that equal to a get component data from entity this time we're gonna pass in the delete tag here and then lastly we need to set the command buffer however to do that we actually need to initialize the command buffer where we start that is we're gonna do a private variable outside of here which is the begin initialization entity command buffer system so you know it's pretty self-explanatory exactly what that is and we'll just call that the buffer system I know it's a whole bunch of words but basically this is just how we initialize the command buffer and then here we're actually gonna need to do a protected override void for uncreate and then in here we can do buffer system set that equal to world that get or create system passing in a type of begin initialization entity command buffer system so now we can go back into the on update set the command buffer equal to buffer system dot create command buffer so that's pretty much how we initialize this command buffer here again we start with this private begin initialization and 2d command buffer system just call that buffer system and then we'll set that equal to world get or create system they'll make me say it again but you get it and then so the command buffer we set that equal to buffer system that create command buffer so again that's just how we create this command buffer which is gonna allow us to you know add components to entities pretty much alright so anyways we're done initializing the trigger job so we'll just do a semicolon at the end there and then of course we need to return from this on update function so we're actually gonna do a return trigger job dot schedule so we're doing a dot scheduled this time instead of a dot run this means that we're going to be scheduling this to run on one of the worker threads as opposed to the main thread and then so if you open the parentheses you'll see that we're going to need an eye simulation a reference to the physics world as well as the input dependence so again outside of here this is just going to be a private build physics world will call it build physics world also we're gonna do a private step physics world call this step physics world just like that now in the oncreate we just need to initialize the builds physics world so set that equal to world get or create system again just passing in build physics world here and then to initialize the step physics world same thing we're just gonna do world dot get or create system passing in the step physics world so now that we have our step physics world we can pass in the step physics world dot simulation and again next we need a reference to our build physics world dot physics world and then lastly we can just post pass in the input dependencies which we got just from the on update function here and so that is our very wordy trigger system so we can just go ahead and save that now real quickly we're gonna head back over to our delete system to add in a few tags there and so after we have our pickup system created real quickly we can just go ahead and add the always synchronised system tag and then one other tag that we need to add in is the update after tag and so we're actually going to update after type of pickup system this basically means this function here is going to update after the pickup system has been completed now you remember the pickup system is where we put this tag on so of course we want to check if the delete tag is on the object after it would have already been applied to the object head back over to unity will let it compile make sure we don't have any errors fingers crossed and looks like we are all good so now we can test it and if all goes well when we hit play here we should be able to run into these cubes it's gonna tag that cube with the delete tag and then it's actually gonna go ahead and delete it so let's see how well this works and we hit it boom goes away goes away goes away goes away goes away and you can actually see over in the entity debugger where it has the pickup cubes here when we're running into them actually being deleted out of the entity debugger so it is literally deleting these entities so those entities are no longer there there are thing in the past okay so now we have our basic role of all working now is the time to add some kind of quality of life features and we can kind of start adding in some mana behaviors and we're gonna have the entity component system start talking with those mana behaviors so the first thing that we're gonna do is add in a game manager and this is gonna keep track of our player score so real quickly I'm just gonna add in a UI text component here all right so now we just have this basic score counter up here and this we're gonna be using to keep track of score so we're just gonna go ahead and create an empty game object here let's reset that transform because you know that's what you do we're gonna call this our game manager and then just at the root of the scripts this is where I'm gonna add in the scripts here so I'm gonna go ahead and add in a new C sharp script here which is going to be our game manager script double-click that to open and mm-hmm good old mana behaviors isn't this a sight for sore eyes right now after all that weird ECS programming that we've been doing so here's the libraries that we're gonna include system collections unity engine unity dot entities you need mathematics unity that physics unity engine dot UI and unity dot transforms so I am going to make a public static game manager called instance just gonna go ahead and make this a singleton so we can access it to increase our score pretty easily so if you've done some programming in unity a lot of this is gonna be pretty familiar so I'm just gonna go ahead and run through what I have here of course I have a public game object for a ball prefab because we're actually going to be instantiating that through code here and converting it to an entity so that's pretty cool you do a public text object for the score text so of course we can increment the score text and then we have private variables we have an int cur score we have a private entity for the ball entity prefab which is what we're going to be using when we convert the game object ball prefab to an entity prefab here next we're gonna need a private entity manager called manager and we're gonna use that to actually instantiate the object within our world we're also needing this private blob asset store which we just call Bob asset store within the awake function here basically just set up our singleton pretty standard now for the manager we're gonna set this equal to world dot default game object injection world dot entity manager again this is just a weird way of saying set up the entity manager for blob asset store setting up that is much simpler you just set that equal to a new blob asset store next we need the game object conversion settings called settings and we'll set that equal to game object conversion settings dot from world passing in world dot default game object injection world and the blob asset store now again it's just a very verbose way of setting some things up so we can spawn entities within our game and then lastly we'll just set up this ball entity prefab and we'll set that equal to game object conversion utility dot convert game object hierarchy passing in the ball prefab as well as the settings that we just set up here so basically this just kind of takes our game object prefab and turns it into an entity prefab so it's not instantiated yet it's just it's ready to be instantiated and then one thing that we need to make sure that we do within an on destroy function here is we need to do a blob asset store dot dispose and that just kind of cleans up all the memory so the next time we run our game it doesn't have the blob asset store from the previous instance of our game okay so moving on down just have a simple start function which sets the current score tells it to update this score display as well as to spawn the ball here we have a public void for increased score and want this to be public so we can access it from another function within our code and all we do is we just increment the current score and then we update the score display you can see that all we're doing for updating the score display we're doing score text dot text equal to score passing in the cur score here so then lastly here is our spawn ball function and basically what this is going to do it's gonna say entity new ball entity is equal to manager dot instantiate and we're gonna pass in that ball entity prefab which we created up in that awake function so again this is actually what's gonna be using the entity manager to instantiate the game object in our world and here we can actually set the translation the basically the position of the ball and so if we want we can set this to five F so this is actually going to spawn kind of up in our world and then drop down so you'll see that and then the last thing that we need to do is just actually add the component data of this ball trans we created here this translation and then actually assign that to the new ball entity so if we save that we can go back to unity here and start setting things some things up on our game manager so of course we'll add the game manager script to the game manager component so now we can take the roller ball and we'll put that in our prefabs folder we'll make that a prefab and then put the roller ball on the ball prefab here and then we can actually delete that roller ball out of our scene because we're gonna be instantiating it through code of course then lastly the only other thing that we need to do is just grab our text and apply it to the score text so now when we hit play see that the ball spawns basically five units up and drops right down and now when we roll around see that we can collect them however the score is not incrementing because we actually need to call that score increment function so we're gonna be doing that right now all right so we're actually gonna call the increment score function from our delete entity system so right before the command buffer destroy entities what we're gonna do is just do a game manager dot instance touch increase score and then one thing that we do need to do remember I said that we're gonna come back to this script here is when we do this unfortunately we can't use the burst compiler so we have to do an enter and dot and we just say without burst and so this is gonna turn off the burst compiler for this particular function here and this is gonna allow us to call the increase score on our game manager so if we save that we come back to unity and we have no errors or anything so that's looking good go ahead and hit play here and then again the ball should spawn into our world drop down and now when we go collect these cubes you'll see that the score increases one two three four five you know and then we can make sure that we go all the way up ten eleven and twelve so we've collected all the cubes now one thing part of the classic rollerball tutorial is to actually get the camera to follow the ball so that's the next thing that we're gonna do and this camera follow script is actually going to be another monobehaviour however it's a little bit different than a traditional one of course because we're going to be looking at the ball entity and we're gonna be looking at its translation component and from that we can kind of calculate where the camera needs to be so it is a traditional model behavior however we're doing some untraditional things of it by integrating it with the entity component system so let's go ahead and do that right now so again just at the root of our scripts folder here I'm gonna go ahead and create a c-sharp script and this will be the camera follow script so here the libraries that we're using our unity two entities unity that transforms you need mathematics and unity engine and like I said this is just the camera follow class deriving from monobehaviour and again we're gonna make this a singleton so just public static cam to follow call this instance we need a public reference for an entity and this will be the ball entity we need a public float three called offset again this is similar idea to a float to which we used earlier you know this is kind of the equivalent of a vector3 but it's a little bit more lightweight because it doesn't have a whole bunch of data associated with it and then lastly we need a private entity manager which we can just call the manager in our wake function here we can just do the standard singleton setup stuff here and then we just need to initialize the manager to world that default game object injection world entity manager and so of course because we want our camera to update every frame we actually gonna want it to update at the end of every frame so we're going to do a late update within here we're just going to do a quick check on the ball entity if it's equal to null just go ahead and return from here here we're just gonna do a translation component for the ball position we'll set that equal to manager dot get component data of type translation of course and then here we actually pass in the ball entity itself so this just basically gets us the 3d position in the world of the ball so now we're gonna set the transform dot position of the camera equal to ball position dot value plus offset and so we can go ahead and save that then real quickly just on our game manager on the spawn ball one thing that we need to do is we'll set the camera followed instance dot ball entity equal to this new ball entity so the camera has a reference to the actual ball entity and I'm going to go ahead and put this back to zero point five just to spawn it right on the floor right then of course we'll go to the main camera apply the camera follow script and I'm gonna do an offset of eight point five in the Y and negative eleven point five in the Z so go ahead and hit play here and if all goes well the camera should now follow the ball so yep for rolling around and the camera is following the ball it just as expected and this is a pretty good-looking roller ball this is pretty much identical to the classic roller ball tutorial however because it is dots you know I'm gonna add in that last little crazy effect and so I'm just gonna show you how to do that real quick it's pretty simple to do alright so this actually all takes place within the game manager script here so I've added a couple more public variables so I have a maximum score so basically when we reach that maximum score we're gonna trigger the insane mode of a public variable for how many cubes I want to spawn per frame of course we have a public game object for the cube prefab a public float for the cube speed which we just set to three right now this is the initial speed of when it's shooting out a couple private variables we have just a bool for the insane mode as well as a private entity for the cube entity prefab only thing we need to do in the awake function here is just convert the cube prefab into the cube entity prefab down in the start function just make sure we set this insane mode to false and in the update function we're gonna check if we're not already in the insane mode and our current score is greater than or you go to the maximum score we're gonna turn on insane mode set that to true and we're just start this co-routine which has spawned lots of cubes so basically this just checks while we're in the insane mode respond however many cubes that we define in our cubes per frame so we're just do a yield return null and this will just return every frame and then the spawn new cube is gonna look much similar to this spawn new ball basically we're just gonna create an entity new cube entity called manager instantiate the cube entity prefab we'll set our vector3 net direction to vector 3 dot up we'll set our vector 3 speed equal to Direction x the cube speed which that value with it we set up there and then we're gonna get a physics velocity component called velocity and we'll set that equal to a new physics velocity we'll set the initial linear speed equal to this vector 3 speed we're just gonna set angular equal to float 3.0 cuz we don't need it to spin or anything by default and of course we're just gonna do it manager that add component new cube entity passing in this velocity component and so that's all good I'm just going to make another cube here and I'm going to change just a couple things on here so this will be the spawned you call it that so it's gonna be a little bit different instead of making a kinematic we're gonna make it a dynamic so that it actually is affected by gravity and everything like that and we're gonna turn off is trigger so then this can like you know collide with everything and do all kinds of crazy stuff like that and I don't think we actually need this rotation speed data component so we can just remove that but otherwise that's looking pretty good and I'm just gonna go ahead and save this spawn cube as its own prefab will do a prefab variant so we delete that now on our game manager we'll just put in the spawn cube variant onto our cube prefab set a max score of 12 cubes for frame set that to 10 and I think that's looking pretty good and this is it baby the final rollerball here we go and collect the cubes of course the camera is following the ball just as we want it to and here we go are you guys are you guys ready for the insane mode and of course you can see up in the editor here insane mode rollerball cubes so much fun and you can see in our entity debugger like if we look at our stats okay my my frames per second dropping a little bit we're at about 40 frames per second we have about you know seven thousand entities within our scene you know all doing these gravity physics calculations so that's pretty good I suppose if we actually made a build of this game it would run a little bit better while we're not you know taking in all this debug data and everything like that but anyways that's how you roll a ball in unity ECS so once again that is how you roll a ball in unity using the new entity component system I hope you found this video helpful if you did make sure you leave the like and feel free to subscribe the channel for lots more videos on the entity component system and the data oriented technology stack of course if you have any questions for me or suggestions for future videos feel free to leave those down in the comment section below but I hope you have a fantastic rest of your day and I'll see you in the next one [Music]
Info
Channel: Turbo Makes Games
Views: 19,938
Rating: undefined out of 5
Keywords: unity roll a ball tutorial, unity rollerball tutorial, unity rolling ball, unity dots tutorial, unity dots physics, unity dots explained, unity data oriented design, unity data oriented tech stack, unity data oriented, unity data oriented technology stack, unity 2019.3, unity 2020, unity dots tutorial 2019, unity dots tutorial 2020, unity dots physics tutorial, unity dots, unity ecs, unity ecs tutorial, unity dots for beginners, learn unity dots, how to learn unity dots
Id: KwwHvH3GZsQ
Channel Id: undefined
Length: 59min 17sec (3557 seconds)
Published: Fri Jan 31 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.