2D PHYSICS! // Game Engine series

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys my name is ashana welcome back to the game engine series thursdays is game engine series day hazel 2d day or at least thursday's in like australian time that's why today i started the day off with doing a four hour live livestream four hours 16 minutes just working on hazel 2d and figuring out what we're doing this episode this is every thursday every thursday on twitter tv slash the churner definitely check that out if you're interested in a little bit more of a deeper look into what actually goes into like you know hazel 2d um and every kind of i guess every decision that's made by me every problem that i suffer through all of the debug stuff because what i do is i basically live stream everything on twitch like i've been doing every thursday this is the second consecutive thursday and i made it so you know we're going strong um but basically this is what we are going to be taking a look at today it's going to be based entirely off of this live stream i've already kind of got the code written and furthermore after the code is basically done i push it onto the public hazel repository in the dev branch you can see literally just straight out of that four hour live stream i'm now recording this this episode so it really truly is game engine day or game engine series day but anyway the point is that um all the stuff that i produce out of that live stream usually i will push that into this branch so if you want like to be a little bit closer involved with the development of hazel 2d definitely check out both the hazel repository this dev branch right but then also the actual twitch live stream where i will be streaming every thursday they just wanted to kind of give a little bit like of a reiteration as to where we're at and how the how the development's actually going now that being said another great kind of thing to come out of this is that i can kind of show you guys what we'll be achieving in today's episode ahead of time i mean i'm sure you could just jump to the end and take a look at it but if we actually dive in into hazel and take a look at um you know what is in that dev branch currently in the code that we have you know we've gone from basically just being able to uh you know render a pink cube hit play we can see it to now actually having like physics where we can hit play and you can see we actually have like box 2d physics running so that all happened like we went from zero to that to this working in like four hours right and that was all live streamed um of course i had you know big boy hazel hazel 3d hazel dev whatever i had that for reference and that's kind of how i built that stuff but again point being if you want to see that whole process head on over to twitch because this is going to be a condensed version where i'm going to do it for the second time but now in front of you guys and hopefully maybe even explain a little bit more so without further ado let's dive in and take a look at what's going to take to make that stuff happen i just feel energized today to be honest because again just done so much so much stuff um there's actually a few other things that went into it that i'm not going to talk about right but i am mostly going to be using this as like kind of like a diff so that i can actually see what's going on because obviously the all of the changes are kind of here and we're going to kind of start with that but the first thing i'll do is actually uh check out a copy of the master branch i think okay so what i have here is a completely fresh checkout of the master branch but it looks like it doesn't even compile and so i want to talk a little bit about this because i went through this on stream and i think it was kind of uh it probably will be useful to some people so first of all why doesn't it compile it's a fresh checkout yeah it doesn't compile surprisingly not my fault um because people seem to have like accepted pull requests without even checking to see if it like compiles or whatever i think the problem is this actually it is this so this log.h file uh now includes stringcast from glm and that's like a gtx thing anything in gtx is like uh experimental as far as i'm aware so um it's good that we have these operators now it's fine but again it doesn't compile because you have to enable the experimental thing now you can just look at the kind of log i guess and see what's changed recently if you knew that it did compile at some point but i'll show you how to kind of diagnose an issue like this because it can be annoying so what does the output say well the output says there's a fatal error glm gdx dual quaternion is an experimental extension blah blah if you double click on this you get taken to dual quaternion.hpp and then we we see the error it's just a hash error the compiler compiler's giving us an error because this is not defined so we need to define this somewhere but how do we even know what's pulling in this header file so the way that i like to do this is first of all you need to figure out like what you're trying to compile that doesn't compile this right so if we look at like the output it can be a little bit hard to tell what even tried to happen but you know if you look at this build starter project hazel it says h.p.c.h and then immediately the error right so most likely it couldn't compile the pre-compiled header so the next step is to open up the compiled header and just hit control f7 on the cpp file this is just to confirm that we are in the right place and you can see that in fact yes the pre-compiled header it's this is the physical cpp file that's trying to be compiled and it cannot be compiled because uh obviously we're getting this hash error so now we have the tedious issue of like but but which one of these header files includes that so easiest way to check at least in my experience is to go back to that cpp file um and then if you go to properties right click properties or alt enter as i just pressed if you go into um cc plus plus and then like i never know where it is so i end up going to all options and searching maybe it's in advanced yeah it is in advance so show includes right and you can just enable it just for that file you can enable for your whole project but that's unnecessary so just for this file we'll enable show in close we'll set that to yes and then now when i hit ctrl f7 i'll see the entire like hierarchy of stuff that's been included now usually it's a bit hard to deal with here so i can just control a control c that and then if i open up vs code which is a command for some reason and it's just a bit weird but if i open that up let me just try and get a blank thing going and if i paste that in here now i have this text here and it's a bit easier to deal with i can find the file that's causing the error which is i think it's this one dual quaternion but i can make sure by just double clicking it yeah so it is dual quaternion.hpp i can find this dual paternity or hpp i can see what's including it which looks to be it's included once and it's included here and then i can be really cool with this multi-line thing in in vs code and i can just middle click drag up and i'm just trying to basically just form a line to see the first thing this is great isn't it to see the first thing that crosses that line to the left right i may have already gone past it i don't know i wasn't really looking um so this is this touches it i'm not interested in that i'm interested in stuff that's to the left side of it so apparently nothing yet um let's keep oh there we go right and then you can see oh look so the first the file that includes that file that's what i'm looking for what file includes that file it's gtx stringcast.hpp that's this what includes that oh look it's one of our files log.h and of course we knew that from looking at the diffs and looking at the actual commits but log.h is the file so going back here going to log.h we'll obviously see that it includes that stringcast as it said in the kind of show includes thing over here right so then we're like oh okay so including this is the problem and what is the problem the problem is that we need to define that um kind of well we have to have that define jill enable experimental if we want to be able to actually include it now two there's a lot of ways you could do this we could stick this in like a breaking ball header we could um you know we could uh actually make the define be part of the pre-make build so that whenever we build a hazel file that already has that defined um i don't know to be honest what it should be i'm pretty sure we do define this in other places yeah we do it in math.cpp we do it in a bunch of places so just for now i'll just do it here as well so we'll define that before we include that file and then the other thing i'll do uh quickly is i'll actually drop this below this right so usually what we do with hazel is we like to include our files first and then anything external just so that like just in case we have certain definitions or certain other configurations pushing warnings whatever it might be that we actually want to kind of take effect before we actually pull in external code so usually we do that um but yeah that's pretty much how i would go around go about fixing and finding the like where that actually is where that problem is um because it can be obviously a complete nightmare to be like oh no this is being included but from where and obviously recursive like not recursive includes but includes nested it includes like it's it can be an absolute nightmare to debug so that's kind of step one in this episode a little bit annoying but um uh fixed uh you know um i guess i'll not being defined in fix that not being defined in log.h um in race and commit so yeah so but just for the future um obviously make sure you test you test your pull request i'm not sure how that would have compiled um unless and again obviously i just did a fresh checkout i ran set up i you know did regenerate i did generate my projects for the first time so it wasn't something that might have also been in pre-make like defining that or whatever so um make sure code compiles that that's you know step one is compiling step two is running try not to fail step one at least um but yeah so that's the first thing i wanted to mention uh other than that we can just get right into basically um figuring out uh everything that needs to go into box2d so the first thing i want to start with is if you guys don't know what box 2d is it's a it's a pretty good it's a great i'll say it's a great 2d physics library you should start with this right i have used this for years so i kind of know how it works so i'm not going to bore you with this here i'm not going to teach you box cd because they have pretty good documentation boxer.org documentation start with the overview go through this it literally like just explains everything really well there's a hello box 2d which goes through how to create a world you can see how good they have little snippets of source code it's fantastic this is how you learn how to do this stuff right um i would definitely recommend taking a look at this it's probably a good thing for me to read it as well because 2.4.1 don't think i've used that version yet and um you know i'm sure there's a lot of stuff that i didn't read initially and probably some new stuff so start with the documentation for sure but then um obviously we're gonna brush past that the other thing that i like to do that i do with a lot of the sub modules is i fork them so i forked box 2d already i actually updated this recently i think so you can see we're like in sync we're kind of ahead because we've got our own commits here but the reason i do this um i explained it during the live stream i might even i don't know might talk about this some other time as well but uh the point being is that i like to i like to fork repositories and put them kind of under my control so that i can freely modify them not just like add a premade file because i want to compile this through pre-make you can see how easy this script is right box 3d is a great example of just being easy to compile no real problems with the build there but um i can just easily make my own pre-make file and add that there so that i can use it with the rest of like hazel's build system but also i can modify stuff so i'm goi is a great example we have done a lot of modifications to imgui um written custom code you know i fixed bugs in there um that's kind of important to be able to do if you're running a game engine you don't want to just depend on someone else's repository unless it's really immutable in the sense that like you're never going to be modifying their code yeah you can make them you can make them directly a sub module otherwise i like to fork it then make the fork a sub module right that's what i've been doing this thus far so i've already done that this has been around for a long time but today four hours ago i when i started that live stream i updated it to the latest version so that it was basically in sync with master right from the original repository over here okay so that's kind of um that's kind of where we sit with box 2d so that means we can easily just go to our um repository and just add it as a sub module right so git sub module add the url and then um hazel vendor and then box 2d i'll add it with the capitalization like this hit enter and it's going to it's going to clone it okay you can see how quick that was actually i mean probably not because i cut but it was it was like seconds one other thing i want to mention about forking as well is that a lot of the times these repositories contain so much extra stuff so like for example this test bed like you know this if you look at this this is like a full on like i'm gui and like you know testing like box 2d i don't need that it should be part of the main repository of course but like i don't need that right so i can just i haven't done it in this case but i could just delete that from the fork and therefore i'm making like the whole hazel solution a little bit lighter right i mean i don't think i'm including that testbed stuff in the build i'm not just source and include but still like those files have to be cloned and pulled down we don't need that right um there's another reason why i like to do this but anyway so we've got that sub module um it's set now now all we have to do because again i've already written the premade file for it this sub module is in use by big hazel as well not just hazel 2d um which is this version that we're working on here the game engine series so we've been using it for a while but um hazel vendor box 2d it's here right and it's got a pre-made file so all i have to do is like add it as a as a like i have to include it into my pre-make file and add it as a dependency so i'll open up dependencies.lua and pre-make 5.lua so i probably will try and keep them kind of in alphabetical order maybe i'll have the lowercase guys first here for whatever reason um i don't know what order to put these in like you could try grouping them by categories like this stuff is all kind of graphics related glm's like math it's kind of core i guess entity like shaders i don't know i'm just going to put it up here workspace location hazel vendor then box2d and then box2d doesn't that that does in fact have a folder called include which has all that stuff there now we don't need to include the library directory because we're not linking it as an external library we're actually compiling it ourselves so because of that we can just go to pre-make five dot lower and over here in dependencies we can just include it again i'll include it kind of in alphabetical order kind of and actually i guess that is an alphabetical order except for that but um box duty is now included so it should be included in our dependencies over here sorry over here dependencies um but then there's a few other things we have to do to specifically hazel to actually link the library and also add those include directories that we just defined in dependencies so if we go to um let's say hazel and then look at hazel's premade file then we can say that we want to link box 2d again i'll do it in alphabetical order it shouldn't matter too much um and uh the include directory again i guess in alphabetical order so box 2d and i think that's it i think that's literally it so you can see how easy it is to set this up if you already have that pre-make file so now i'll just regenerate those projects again you can see it's made the box 2d stuff if i hit reload then i guess the pre-make files are included in pre-make that's kind of nice right yeah that that that's nice i didn't notice that before um anyway so we have box 2d here let's right-click and hit build try and compile it should compile without problems i hope debug x64 my visual studio lately by the way has been just a complete disaster i don't know what's going on like look at it it's just frozen now just frozen trying to compile stuff there we go finally started the build and there you go you can see how quick that was of course with multi-processor compile enabled and my like 16 cores it's pretty quick but um that's done no warnings no nothing we have the lib file and it should be linkable and everything should be great so that is how we add a sub module really easy stuff uh again box2d is quite a simple example weren't many source files nothing really too you know it's just math basically box city so it's it's easy to work with okay so let's pop into this and see what we can do i'm just gonna hit a five to to run this um it should just link it i think i added it like i didn't forget to add it to the linking did i um let's compile the rest of the engine visual studio is not responding i don't know what's going on probably need to wire my computer again or get a new computer because this guy is getting old um anyway while that's going though um let's uh talk a little bit about our strategy here so what i want to do is like the idea itself is really easy and as i mentioned looking at the documentation is the best the best way to get started but what i'm going to do today is specifically just make it like you know i'll get it to the state that i showed you in showed you at the beginning of the episode look at this it's still not responding what a pile of trash anyway as i mentioned we'll get to the state that i showed you in the beginning of the video but to do that all we really need to do is basically i don't think we have now seen in our same class i don't think we have an actual like entry point that we established like a runtime start function you know editor layer we made that um on scene play or something like that we made that function uh i think last episode which i'll have linked up there by the way i should've done that it'll probably be linked since the beginning since the beginning of the episode but basically you know we have that play button but it needs to actually trigger something in the scene because at that point we actually want to initialize the box 2d world and populate it with all of the rigid body 2d components that we're about to create and then all of the you know box colliders or whatever else we have so that needs to happen when we hit play and then obviously every frame on update we then need to actually simulate that physics world and then that's basically it so the way that it works um probably worth explaining actually i didn't even think about this i was just going to jam in the code but i guess if you've never done this before it might not make too much sense so let me switch back to my screen again this is very crude because i didn't prepare for this we're gonna we're gonna just maybe i can um fill this with just like black or something and then draw in white so that my screen isn't so my um face isn't overexposed that's the real reason yeah i guess i can so basically the way that this works um in paint is uh you know we have this kind of box 2d world which contains a representation so i'll call this box2d world this contains a representation of all of the actual physical bodies that we have in our scene so we call these rigid bodies they are literally if you just imagine like oh i have you know if we look back to that scene that i showed at the beginning of this episode we have like a box we have another box this is like kind of like the floor this kind of moves around and bounces around right so these are both rigid bodies this one we call a static rigid body because it does not move right or at least it doesn't like it it's not really affected by gravity or by physics itself you can't push this around of course programmatically you can decide to move it somewhere else but it doesn't get simulated right it basically adds as it acts as like a fixture as like something that's permanently fixed now this on the other hand is a dynamic rigid body um in the sense that like when you hit play it will fall right if this was also dynamic the floor would just fall and that would be useless right that way this is kind of fixed it's being kind of held by imaginary pins of course in the real world we have like you know the earth floating in space it has a gravitational center this isn't really the case for box 2d or anything so that's why we have this concept of static because we need to be able to fix something in space otherwise everything moves and that's a disaster right so we have these rigid body 2ds they also have something called a collider right they have to have a collider which specifies what part of it actually kind of gets uh sent to the physics system so the fact that we're rendering this as like a square and i think that's all great that has nothing to do with like the physical mathematical representation of um our actual bodies here right so usually what happens is um you know physics libraries like box2d like to deal with half extents so in other words you have a position which is basically the center of the object and then you have a half extent which is basically kind of like the radius instead of the diameter right so it's not the total length of this thing it's from that it's from that position point how long till the edge right so in other words if this was a one by one meter square like this then obviously you'd have a 0.5 by 0.5 kind of box collider extent right that would be the size of the box collider 0.5.5 so that's how we basically like this mathematical representation we give to box2d and then it's able to basically run a simulation right so this will fall on that mathematical representation but then what we want to do is show that so we need to basically take that back and render that on the screen somehow right so how do we currently render things well we use the transform component right so we have it we have a transform that contains like our translation rotation scale right that's what we use to actually physically draw this so if we want to draw it down here now right we need to obviously pull that data from box 2d so in other words in this case we'd be pulling well you know this is 2d physics so we just need the xy position right of where it is there is no z positions that is zero and then we also pull just the z rotation right so in other words you can't rotate it in 3d space you can't just suddenly make it kind of lie down like that it's going to be like rotated this way right so that's a bad drawing rotated this way right which is obviously going to be through that kind of depth that z axis so that's what you need to do um we need to pull that back so in other words we first basically when we hit play we give box 2d all of these representations all these mathematical representations we tell it hey this is static there's a lot of other kind of properties as well like you know the friction of a surface the bounciness or the restitution of a surface like there's a few different other things like the density how heavy is it stuff like that you know we can give it um way more parameters than just like this is where it's located and that's it we can give it like physics material properties basically but at the end of the day you know this is just what we're dealing with right we're dealing with these parameters that we give to box to d and that happens when we hit play now every frame we need to update all of these bodies right so we basically tell the box 2d world to simulate our physics and then once it does that once the simulation has completed right we need to actually go through all of these box 2d bodies basically and pull this orange data back and apply it to our transform component before we render it and then we render it and then everything's great it's been affected by physics now there's a few important things to note here right feeling energy i'm standing still we're standing during the entire four hour 15 minute live stream and i'm still standing have not sat down today that's that's how that's how into game engine series day i am but anyway so the other important thing to note here for sure is that since we are pulling our transform data and overriding our transforms every frame from box 2d that means the transform component can't really be used anymore you use it initially to set up where you want to be in the world right because when we create those bodies in the first place when we hit play right where does it get the stuff for like where the body should be from the transform component so that still acts that still works in that regard but then if we suddenly decide through our c-sharp script in the future that we want to move a body we can't just set as transform because that's not going to do anything when it gets simulated it's going to set it to whatever the box 2d value is useless right so instead of doing that what you need to realize is that if you are if you are a rigid body if you have that rigid body 2d component right then you you are owned by the physics system that means that if you want to suddenly decide that i want to teleport myself somewhere else into the level during gameplay you tell box2d to do that for you right because again box2d becomes the authority for the transform essentially of the actual object of the entity so that's important to note as well you can't just set the transform not gonna work you could make it work if you wanted to if you really wanted that api i want to set the transform because obviously behind the scenes in the c plus code you could be like if the transform is being set from c sharp and i'm a rigid body then redirect that transform setting to box 2d you could do that internally but i find it's a little bit better to just be aware of how it works i guess and of course in your c-sharp logic code you could also be like if this has a rigidbody2d component set it that way otherwise set the transform directly so whatever anyway that's the plan hopefully that explanation was kind of useful now we're going to dive in and actually start doing all of the work so this has finally loaded by the way so if we go to scenes uh and yeah we've just got the pink cube here we hit play everything works um now we can actually compile and run that's kind of nice but of course we don't have any 2d stuff so how do we even set something up right so if i go control n i'm going to set up and by the way during the live stream i was very annoyed with the fact that there's so many things missing like we can't duplicate entities control s didn't exist during the live stream i ended up adding it so we can only save as we can't even save right so i might i don't know if i'll do that today i might just merge it in or something i don't think that's that interesting uh but basically if we create a kind of sprite render entity our first goal i'll create um i'll call this our sprite right i'll create a camera as well call it camera and this camera the first goal of the camera will switch it to like perspective and then i think we'll just pull it back a bit now if i hit play you should see that that's great so now we're going to save as i'm going to go into assets scenes and we're going to call this the same thing it was in the dev branch physics 2d dot hazel done so now if i go to uh you know pink cube and then go back to here you can see that it saves my scene and everything works wonderful i want to make this fall that's step one right if it's really part of the box 2d world when i hit play it should fall right if it's a dynamic rigid body how do i make it a dynamic rigid body well i would want to go to add a component and add rigidbody2d and then also add a box collider2d so we clearly need all those components but in the first place we need to even get boxcity into our engine i mean it's already compiling as part of our engine but obviously we don't have it doing anything whatsoever so this is now where i'm going to refer to the code that i wrote during the live stream because i obviously don't remember everything that happened so basically the first thing we need to do is store a box2d world right again consult the box city documentation but this is called a b2 world now i don't want to include box 2d here because if i do that c dot h is likely i mean it's definitely included by hazelnut it's incl it's going to be included by the runtime potentially and stuff like that i want to keep box 2d as like a hazel thing only so i don't want to have to link box 2d and like use you know set up the include directories for box 2d for every project from here on out that uses hazel i want it to be a dependency of hazel not of everything that hazel uses so because of that i'm going to do a four declaration here so b2 world right has to be outside of the name space here i could put it here and just do like a blank namespace but i'm not going to do that and then we're going to add it as a raw pointer yeah that's right unfortunately unique pointers can't be um incomplete types so otherwise i'd probably use a unique pointer or something but then again we are actually manually going to be creating this and destroying this pointer when it comes down to starting and ending our runtime which would be a good place to introduce this so on runtime start and on runtime stop so these two functions which i might hook up immediately so that i don't so i don't forget about them um [Music] so where does this happen on scene play right so on scene play we'll do on-run time there you go man there you go visual studio okay uh what is it it's active scene look at that active scene on my computer just i think my computer's more tired than i am from all the programming today to be completely honest on runtime stop uh it doesn't really matter like what order you do it in i did it in i did it in the opposite order of this in the dev branch i'll do it in this order here why not um but basically these two functions right which we will implement um these two functions are going to create and destroy our box 2d world so uh we'll include box2d here so include um what is it uh box2d slash b2 underscore world from memory not sure why that's not helping me until a sense intelligence has been kind of broken all day anyway but um uh what is the box 2d world equals new b2 world there you go intellisense is back catching up with me so gravity right it's a v two it's a b b two vec b two b b two vector box to a vector two so no horizontal and then we'll use minus nine point eight that's the kind of nine point eight what is it meters per second the normal gravity we have i think on this planet i'm not a not a not a physics person so i don't know sure checks out um might want to look might want to look that up uh i'll do i'll call it this physics world right come on i'm using like one of my old keyboards it's a dust keyboard i think three but it's the ultimate version which has no like no um the the keys are blank basically it doesn't have any actual letters text glyphs whatever on the keys so if i miss a key if i'm just typing it's fine but then if i have to press a key and especially a symbol don't ask me to because i'll be like oh no i'll start doubting myself it's a disaster anyway probably not great for recording videos but whatever um so yeah so we created this box 2d world and this happens of course inside our uh kind of on runtime start function and then what we want to do now is actually go through okay well actually since we have since we've created we might as well destroy it so we basically do delete and then we'll uh also set this to null pointer because of course the scene isn't dying um so we want to make sure that if in case we're debugging or whatever that it is in fact null points and not whatever memory address was left over that we deleted deleted the data from um yeah so what do we do next well now that we have the world we want to start adding bodies to it how do we do that we call the create body function but we need to know what entities are actual physics entities that need to be created so we need to create some kind of physics component so if we hop on over into our components file go to the very bottom i'm going to make a area here called just physics i guess struct um let me pop on over into the right file over here as well so that i can see uh like what i actually did but we'll call this rigidbody2d component so everything in hazel i'm pretty sure potentially apart from no okay sprite render has that as well um they all end in component just so that it's completely clear um but we don't have too many things here um i mean enum class body type right so we have a type for the body so static which is zero again i like to explicitly write it just to be on the same page just in case but it's not really necessary it should be zero anyway static dynamic kinematic um kinematic i don't think we're gonna deal with that today but um it's not so in other words we're not um and then we can actually set it to be i guess body type static by default like that right um now the other parameter that we might want is basically whether or not rotation is fixed so you might want it to not be able to rotate right that's useful to have um and that's kind of it now other things we're going to include here though are a little void pointer this could be a forward declared b2 body pointer but basically this is going to be the actual runtime body so we're gonna inside the component itself we're actually gonna store the runtime body now i don't know why necessarily i decided on this architecture i did this like over a year ago for for big hazel um you could easily have like a map of entity id we don't have uuids yet parentheses but you could easily have a map of that to these void pointers or to b2 body pointers if you wanted to in the scene so scene could own that i don't know if shoving it into into a component's a great idea but then again i don't think it matters too much unless you believe in the whole they should be immutable i don't really know um i think it's fine this is eight bytes of memory it's just going to be a pointer to a runtime body so that we can keep track of it through box 2d that's all it is um that's it right so after that we create a default constructor and again i just like to be explicit about this and then we create a copy constructor as well i guess we can just do that if we wanted to but um yeah i guess what's the point of running other um okay there you go so that's the rigid body 2d component now i want to do the same thing now but we'll do it for the box collider 2d component right so this is going to actually represent the box um that we are going to that is our collision box right so it does not have to match the sprite obviously it can be whatever you want it to be um so let's get rid of this stuff with the exception of we'll keep this we'll call this runtime fixture because we'll have to we will we will want to be able to kind of um reference that so we will create an offset which we're not actually going to use today but this will just be for future reference this is if you want your collider to be offset from the middle of your entity right um from the mid from the basically from the transform position um size as well by default we'll set it up to be 0.5 um so this will line up well with a one by one meter sprite which again if you create like a sprite renderer component it's gonna be a one by one meter um like according to its transform a one a one by one scale i guess one by one by one scale means that you have a one by one meter object so this is going to basically follow that convention because these are half extents so you will still end up with a one by one meter thing now um the rest of the stuff is basically like physics materials stuff so we have a density which i just said to one by default i don't know if these are good default values this just is what it is friction i think i said to you at 0.5 and then we basically have two things so we have restitution which is the bounciness kind of it's like something to do with energy and how much is lost and then also a restitution threshold so this is important because i think i've set it to 0.5 and then by default it's not bouncy right yeah so this is just a threshold at which velocity again the docs explain this greatly um the what this is the velocity at which it stops like calculating the bounciness because as you can imagine if you drop something on a table it could keep bouncing in like forever right infinitely because it's just going to keep like bouncing um and we don't want the physics engine to have to keep calculating that and we'll get weird jitters like so you usually just say this to like something decent was like okay well if the speed has fallen below this amount i don't know if 0.5 is a decent value whatever seemed to visually look fine and you can obviously tweak this that's the point of exposing this value but this basically just means that it's not going to it's going to just quit after a while and be like okay no more balancing which is i think important um all right that's it so this stuff i'll add the same to do i did in the dev branch which was um basically move into physics material in the future maybe um so that we move this uh basically into an actual physics material because that's kind of what it is so now we have those two components right we can basically do the rest of the code here now we still need to set up the ui and the serialization for those components right so remind me um this is not a live stream but remind me um from the past so back into scene right how do we set the stuff up well basically once we have our physics world we we really just need to go through somehow so we'll use a view to go through our entity component system through our registry um and basically look at all of the rigid body yeah definitely that rigid body 2d components that we have right so for auto uh we'll do e in view and then we'll immediately just create like a hazel entity out of it so e and then i think this right um so that we can like use our own api i guess which is like a wrapper over ent over entity so once we have that um we need to basically pull some data so what are we trying to do we're trying to create bodies into the physics world we're trying to create some bodies at particular locations with particular sizes set up their colliders do all that stuff so we obviously need to pull the transform out so we'll do transform equals e get component do we actually have no uh why is this so difficult um do we have no okay so and i think in hazel in um proper hazel we have a dot transform function that we can just use and it's shorthand for pulling out the transform components because it's such a common thing to do but we'll basically and this is obviously with entity so entity get component transform uh rb2d rigidbody2d so this is our rigidbody2d component which we just made um what else do we need that's probably it so now we can actually start creating a body so in order to be able to actually do create body you can see we need a body def that's like a body definition right so um basically b2 body def right this is our body definition and then we can start filling it out now i think we'll probably have to like include body and while we're here we might as well include fixture probably it do we need like shape we're going to use a box collider so is there like a shape polygon shape i think we'll use yeah include everything this is all the box 2d stuff um so we to we'll pass that in so it just takes it in as a constant pointer like that it's going to copy all the stuff internally i'm pretty sure well it definitely does because this will go out of scope obviously um and then we basically set up all the stuff we need to for our bodies the main things in the body again are things that we have here the type and the rotation and that's that's it from the rigidbody component but then from the transform component we need to set the position of it and stuff like that but the first thing we probably care about is the type right so to set this type um i think it's good to like create a little conversion function so that we don't have to have if statements or a switch case in here because we need to now convert from our kind of hazel type static dynamic kinematic to box 2ds type i don't know if the enum will line up because you could just like type on it or copy the value or whatever interpret it whatever you want yeah you you could static kinematic dynamic um we defined it in a different order as will be different i don't like you could so i'll show you how to do that i'm not going to do that just because i like to be a bit more explicit with my conversions but basically what you could do is basically take our rigid body 2d because they're just integers obviously and just be like no no it's this done right i don't think it'll let you apply this just because they will show up at different types but if you cast it it will be fine you could do that again in this case we we would have to switch dynamic and kinematic but i'm not going to do that i'm going to write a conversion function so to do that we'll just do static what's the actual type b2 body type um we'll do hazel uh what did i call the function hazel rigid body 2d type 2 box 2d to box 2d type basically so um so this will be a rigid rigidbody 2d component body type so this is the body type we're taking that in and we're converting it here so you can just do a switch statement for this of course body type and then what do we do case body type static will return static so yeah this is just a bit nicer in general just because you don't have to worry about um [Music] you know this is kind of since we've defined our own types for it it's nice to be a little bit more in control with conversions just in case they change stuff around because obviously they assume if you use an enum it doesn't really matter what the value is unless you serialize it and then again i like serializing enum values as strings rather than as numbers unless you are doing a binary format for runtime that's fine but in terms of like for an editor definitely serialize it as a string because that way it doesn't really matter um you know what's up uh so will chorus at false because that's an unknown type unknown body type i don't know do we need a dot a full stop no um and we'll just return a thing just so it's happy but yeah so now that we've got this we can convert from um i guess i won't call this hazel because we are hazel right rigid body 2d type that's hazel's one obviously to box to the type to box city body um so now that we've got that we can of course do this instead it's a little bit more robust than just assuming that the you know why not um and also in case you're wondering why we don't use why we don't just use box 2ds types here i just don't like to just because i don't i don't like to be dependent on that right like if we decide that we want to change um over to use like not box 2d for whatever reason you know there's a lot of box studio references all around the code i like to be a little bit more kind of abstract i guess a bit further away from implementation details so we just roll our own stuff and then you know we can add translation where necessary obviously this stuff is it's not like gonna affect performance or anything we're in runtime start and we're doing a little little light light little conversion so everything's fine there's gonna be another monster episode well it was a four-hour live stream what do you expect um but at least we're getting we're getting stuff done you know for hazel 2d which which i think is important because i'm getting a bit fed up with how long it's taking us to get to anything uh at least capable of making a small game so um the position now so the position obviously coming from the transform it's great that we store stuff like not as matrices because it's just so easy to grab these values we don't need to decompose anything i mean translation is a bad example because that's easy to get from a matrix regardless but stuff like scale and rotation especially um it's so nice when it's just stored like this speaking of rotation we'll also set the angle notice that's just a float of course because we're in 2d physics land so this will simply be um what transform.rotation.z basically transform.rotation.z all right so that's our body def pretty much done i think now we can actually create the body by passing in that body depth and we have our body ready to go we need to pull that out though so b2 body pointer um we'll just call this body i guess uh so this this is going to be our actual body that we want to store back in the component when we wrote it right so we have a runtime body so this just keeps track of it during runtime otherwise it's null pointer right so uh oh and finally we need to actually set fixed rotation this happens in the um like in the body not the body depth so what is it going to be rb2d dot fixed rotation there's a lot of other stuff by the way i'm arbitrarily picking stuff i don't know even how i came up okay came up with what gets included what doesn't but like if you look at set fixed rotation like there's um you know we can have enabled disabled there's obviously fixed lists there's joints there's a lot of stuff to do right um and obviously even like stuff in hazel that already does exist in in the in the in big hazel is like stuff like contact listeners so being able to get callbacks into your scripts when collisions occur triggers stuff like that that's all ahead of us we will get there probably one day but for now obviously starting with the first pass um yeah and now that we've got this we can go back into that thing and set that runtime body to just be the body right it's a void pointer because we don't want to include box2d there again nothing wrong with just making a forward declaration like we did here um that's okay i think but i just kept it as a void pointer whatever it doesn't really matter we know what it is um it's not a big deal now we could go through this again except this time checking for box collider 2d stuff um but instead of that i'm just going to do if and again from an empty component system i don't know if this is what this is might be worse than just iterating through all of them in a row but this is on runtime start not a big deal i think could change it later if we need to but it's just code wise is a lot it's a lot better to just have it here so we'll just do um if entity has component box glider 2d component we can add an actual box kind of collider to it basically so we'll get that box collider 2d component from it which will be entity get component this right and then we can start creating an actual shape out of it so b2 polygon shape that's what i included earlier so we'll make the actual uh i guess polygon shape could have called it shape i guess uh shape dot set as box and then we set the half extents and you can see it says half width half height they're even labeled hx hy so we could obviously just set this to be the uh x and the y right and oh there is a center so we can actually pass the offset into here that's cool i didn't realize that during the live stream but basically um there's even an overload what's the other one all right with center and angle oh but that's an oriented box this is an access align box um we won't play with this just just yet um so we'll basically we we could just set this to be the uh size dot x and then the size dot y um which is fine but what i want to do is i want to make this not just like an absolute size that we set because you know i mean intuitively you want to be able to just resize your box your renderable box in the actual engine by just dragging like on the scale and making the scale larger and you're making it a non-uniform scale or whatever i want to you know build some walls and stuff like that and then i don't want to manually go into the box collider 2d component and then i don't know be like oh okay now it's 20 meters tall so i guess i'll manually set the y to be 10. like that's just silly right so instead of doing that um we what we do since we are already kind of living in a situation where like we have scale and we're in a one by one like you know one a scale of one means one meter so clearly half of this means half of that and the half extents work and stuff like that so because of that i i'm like i think it's a great idea to basically just be like you know what transform.scale.x i'll multiply this with this size x and stuff like that right so i might do it the other way around um just so that's a bit more clear in the code but uh you know if we multiply with scale it means that we automatically get that scale value in here we'll change it to y and everything's fine now if you want to modify that so you want it to be like a you know maybe different like twice a scale or whatever you can do that and i think if if people really have an issue with this you can easily add a little checkbox to be like don't use scale or use scale and then have a check by default or whatever and then that way you cannot do this here um but otherwise you know if you wanna if you just wanna custom hard-coded value of course it can be a little bit difficult to do but again if you have a scale of one you can have whatever value you want because you'll multiply with one so i don't know i think it's good to do this uh it just makes a lot more sense when you're actually you know using the engine unity does this i'm fairly sure um okay so now we set up the fixture so the fixture is going to contain this shape that we just made a little polygon shape right um i guess we should call this a box shape actually because that makes more sense um and then all the kind of material stuff that i just talked about right so stuff like the density the friction you know all that stuff so where do we get it from we get it from that box collider again that's why i put it there it might have made more sense to put it onto the actual rigid body but you can see that box 2d stores it in the fixture which the fixture needs the shape right so it's all kind of you know connected i guess so we'll get the density from there then we'll get the friction uh then what else is there the restitution and the restitution threshold right so once we've got all of this stuff restitution um restitution threshold and friction right we just create the fixture so we go body which we still have because we're up here that's another good example of like why i kind of did it all in one for loop not in several kind of iterations going through different components just because we already have everything here it makes sense create fixture and then we'll pass in that fixture def all right fantastic so that is pretty much it for runtime start i don't think that's anything else that we need to do so that's fantastic we've created all of the entities within box 2d itself we've got those um you know beautiful orange lines that i drew earlier so now what do we have to do every frame well usually you would want to do this after you update the script i think at least in hazel we like to do physics after we do the script so like with physx and for 3d physics we do it after the reason being the way that i kind of justify this in my head is just that the script can control the physics the script might be like i want to add an impulse i want to add a force and obviously that will not get picked up until the next frame unless you actually um do the calculation after you do that right so in other words what you're kind of the thing you're kind of playing with here is the the render order right versus like the you know the script s and then the physics so if you do script physics render then the script affects the physics and you can already see that in the render otherwise if you do physics script render right then obviously the physics will happen you'll add your impulse but you'll render obviously from the physics so you won't get that impulse until the next frame so that's kind of how i that's why i did it that way um again i don't know what arguments people have i didn't think about it for too long to be honest but whatever so you know physics so um we'll probably start using stop using like 2d all the time because this is a 2d engine but like for this i want to make it clear that this is a box collider 2d and that's 2d just because just because i want to um so how do we do this so i i kind of arbitrarily i think this comes from the either the documentation from box 2d or possibly it's from the uh one of their examples but basically we have velocity and position iterations this is basically controlling the granularity of the physics simulation so how much is it stepping how how often is it doing calculations between moving and stuff like that if you increase this performance is going to go down but the precision will go up so i don't know what good values are this is definitely open for debate and i think that you should definitely probably expose this to the editor in some kind of physics settings because it will definitely depend on what kind of game you're making and you know what app you're making what simulate what scene you have and stuff like that so we pass in the time step which is just ts and then obviously what we just created velocity iterations position iterations all right so next step is to basically retrieve those rigid bodies from the world so that we can actually uh you know update them so what do we have to update well we've just stepped the physics world which means we've simulated the physics so now obviously the positions of things have moved around right the positions of these orange things have moved around so now we have to grab those transforms so that the white squares that we actually render all of our entities in the right place so to do that um you know we'll go through uh auto um e in view just like we did before um uh so yeah i'll i guess i'll make that clear so retrieve uh transform from box 2d right so uh we'll make that entity like we did before and e this and then we'll just we'll basically scroll up here and get the transform and the rigid body 2d components because we need those and then that's kind of like it like it's really quite simple all we have to do is grab that physics body which remember we are now nicely storing inside here so we can just do run time body that's a void pointer i'm going to cast it back to one of these you guys can use static cast or interpret cast if you want we had a discussion during the live stream and i kind of agreed that you know i just like see so i just like see stylecast i think it's fine and i think it's necessary um to write static cast or or interpret cast here um this is avoid pointer and we're just cursing back to here um now if you didn't store it on the component this is where you'd probably want to also retrieve maybe the entity uuid or whatever and then be like hey scene you know give me my entity box 2d body map and then i want to um you know i want to get my entity id and then that way you could kind of get your body that's the only other way i can really think of doing it um sure right but the data's already here it's already hot in the cache i guess because we're going through this anyway and which we need to get the values out anyway from the component i guess so i don't know i think it's fine um i guess we don't really like we do need to go through the rigidbody2d component to know what even to set what entities to set but um i don't know i think it's fine doing it this way all right and it's not that i sound like you know insecure or defensive of my strategy i'm just literally thinking out loud that's all um i don't really care like i'm happy for people to correct me obviously so now we get the position from the body so get position i'm purely using this constant reference as an alias if you look at get position it returns a const reference of this i just don't want to write get position twice that's all um this will probably all be inlined anyway obviously so uh transform.translation.x right so we can set that x translation to be position.x right that's from box 2d and then we do the same for y so we're just copying the x and y position from box 2d into our transform component thus changing our transform component pretty wild stuff i know um and then we'll do the same thing for the rotation so the z rotation will now be position not position obviously will now be body i think it's get angle right because that's what we called it and that's it and this angle i think is a float right so there we go there's our angle we've got the rotation z everything looks brilliant and believe it or not guys that's actually it um that's actually it we need to program all the ui but fundamentally functionally that is actually it so let's try and build this i know it's going to fail because of a few annoying things but we'll still build it um see how far we get i guess um [Music] okay that succeeded i'm surprised because i thought we were missing some like of these annoying things but whatever i don't think we're actually calling out a component yeah that's why um so how do we add can add this stuff right we'll do this utilization last we'll start with the um with the scene hierarchy right so we obviously need to be able to um add these actual entities how do we add like a camera sorry not entities components so we have ad component this is one thing that annoyed me during the live stream why on earth would we um have this set up i don't know if i wrote this or not i don't remember i don't care but you know in this case it's like if you don't have the component at it otherwise just write something don't add the component obviously and just write a little log message that's weird what we should do is not even present that as an option if the component already exists right and by the way if we want to have multiple box collider components that needs to be a completely different system so we'll talk about that later when we get there but um that's definitely like i guess there are use cases for that and it's probably best to have like a box 2d collider or like a a box collider collection component or something that contains many you know shapes and and box colliders within it that's probably how i would do it but yeah if we don't have that then we'll add that and also cleans up the code which is nice doing it this way um so let's do that right all good now we'll copy this and we'll give ourselves a way to add both a rigid body component right so rigid body rigid body 2d as well as a box collider 2d component i should um just locate check my disk space and stuff because i always get annoyed like i always get worried and stressed about these long videos just failing to record or whatever hate that box collider 2d and uh rigidbody2d right box collateral okay that looks good um so now we have the ability to add it but we want to obviously tweak the ui and stuff so let's go ahead and the hardest one is probably going to be let's copy the camera one the reason being that well actually we'll copy the sprite renderer but then we'll grab some stuff from camera because we have a drop down box right and they're always fun to do because we have this like checkbox it's not checkbox but we have to be able to to actually um select what body type we use so we have static we have dynamic uh and we have what is i'm doing from memory by the way just because um well this is ui stuff it's easy but i just did this a few hours ago i'm gonna be have dreams about box 2d and stuff yeah um so body type body type strings current body type string body type strings um and then component so this is uh coming from component dot um i'm still doing sprite render component so this is oh i better not be modifying the actual sprite running component good i'm not so this is the rigid body 2d component component.type i think this is useless yep type cast to it ins um getting that stuff out current body type so this is our body type we'll put in our current body type so basically current progression string gets replaced with that and projection type strings gets replaced with body type strings and everything else should work apart from setting it so to set it we just do component dot body dot type equals um this is slightly annoying but rigid body intellisense being useless as usual although i did misspell that i guess body type uh i right um that's it i think i don't think i did anything with cameras or projections i don't think i left anything there whatever we'll debug it if anything so that looks good that's our body type um what else do we have inside that rigid body component so just just fixed rotation is the only other thing which is kind of nice so i think this is just a checkbox we really need to redo this ui as well because we've still got labels on the right side and you need to integrate some new ui if you guys haven't seen the new ui by the way i'll have it linked up there um if i remember but it's the latest kind of hazel devlog check that out it looks so good and we're going to start probably bringing some of that back into here as well so what is this fixed rotation um so let's see thanks for the help oh no oh no my whole computer is frozen okay so i almost just had a heart attack because my computer froze this mouse would not move for like a few minutes but the rook i stopped the recording and the recording after it unfroze and the recording is safe i was almost about i was an hour and eight minutes into that recording man if that no it's not good for my heart anyway let's get back to it so at least i have the first part saved i wouldn't mind resuming from here if i anyway so component fixed rotation um that's easy enough so so we've got that going um now we just need to do the same kind of thing but for the uh box collider stuff so box platter 2d component box collider 2d don't need any of this stuff obviously uh it's actually pretty simple we just need to basically have um an im gui like drag float two i guess for the so yeah all this stuff from here basically so let's maybe just kind of display that side by side or something um so that we can quickly see it nothing really to do here so we'll have our offset which will be glm value pointer component dot offset [Music] and then we'll have size density friction and these are just track floats density friction residue restitution and residual threshold that's it right okay so these are all just component dot uh now because restitution so if you read the docs right um restitution hard word um if you read the docs then you'll see that um these values like threshold not but like these values are mostly between like zero and one right actually i think it's not even the docs i think it's just like the code that says that so if you look at like density or whatever that's our density um it says that like yeah usually in the range zero one so friction restitution so you don't have to lock it to zero one because again usually in the range means that like not necessarily you know like it could for whatever special effects you might want to exceed that range but again like i don't know if it's worth locking and having a button that's like unlocked because again for most purposes you might want to lock it um but yeah i think what we'll do is we will lock it for now so 0.01 will be the speed and then 0 1 will do all right same friction same for restitution but for the threshold we'll have 0 as the minimum um so this speed so if you're up on one speed zero minimum and we won't have a maximum um because yeah okay that's it i think i know weird checkbox here but that's basically it oh like offset offset everywhere yeah basically yeah well done cherno um so component dot density this all needs to be removed uh density we've got restitution and we just need friction okay so that's basically it i think um have we just done like everything that we needed to do i feel like we might we may have so let's go ahead and hit f5 and see what happens um again serialization is the big thing we haven't done yet we want to be able to save our components okay this is what i was talking about so we need to have um i don't know why i did this man i was a bit i was kind of upset upset of myself on stream for doing this at some point i guess but like why do we even have these i guess if we want to trigger these events when they get when certain components get added like this but i don't know they're kind of enforced everywhere which is weird maybe we should make them optional somehow i don't know it's just going to try and call it if it can't find the if you can't find the function it's linking error so it's not the best thing um but anyway uh we'll just we'll just shut up and add them here in this case copy that across um and yeah now we should be able to i don't know if we've done everything correctly i haven't really referred to my notes much i've just had the screen recorder here so i can make sure everything's recording um but uh if we go to scenes physics 2d if we hit play will we will we see it fall that's the moment of truth guys are you ready play i failed i failed you all oh no no i haven't failed anyone i haven't added the components yet so add component rigidbody2d add component box collativity so rigidbody2d over here we'll set it to be a dynamic um body of course we'll leave everything else as default now let's hit play i didn't fail anyone okay cool now notice how when i hit stop it's gone it's not actually gone it's just down here because obviously um at the moment when we hit play it plays the existing scene there's no resetting scenes usually what you do what what you would want to do and what we do in hazel and big hazel is we copy the entire scene when we hit play so it's like a new scene it's like a runtime scene that you're playing and then that way you delete that scene when you hit stop and you fall back to the editor scene so that's how we do it and that's probably what we'll do here maybe next episode because that is definitely important but yeah let's add another entity we can't save any of this which is annoying we should probably add serialization first but it but just just to kind of test it we'll add another entity um we'll uh let's just uh move this down a little bit i'll actually add like a non-uniform kind of scale so we'll test that out if that works maybe let's back the camera back a little bit more and then i'll add a box collider to it and i will add a rigid body 2d to it we'll make it static this time let's hit play there you go right it sits on the box amazing and of course we could rotate this and it will kind of roll that's great um and then also let's do one more thing might back that camera up even more it'd be nice to have like a picture and picture for the camera so we can see what it says but the other thing we'll do is uh maybe um well let's set the restitution of this a bit higher right it's like 0.5 so now it should bounce hey it's a bit bouncy now right so that's it basically you can see it all working um did not take that much time did it um yeah pretty easy to do the gizmos are using the wrong camera but yeah that's a little bouncy world now we can't duplicate entities either right which would be great because we'll probably add that next episode when we actually add the um scene copying and stuff because a lot of the same code can be used to duplicate entities but uh yeah that's basically it so we can't save that's our last thing so how do we save well saving very easy right um we just need to manually add the stuff into c serializer now again if we had some kind of automatic reflection system probably wouldn't be the worst thing in the world because it would save us a lot of manual code but on the other hand i kind of like the simplicity of this stuff um you know we don't have to have anything crazy people understand how this system works um and obviously once you kind of have your components in place like it's just something you do for components so i don't know i'm a bit torn um i kind of like it to be honest um so uh rb2d component so we'll retrieve this component if it has it of course um and then we just need to serialize all the values which again we just have static dynamic kinematic um and then fixed rotation right but the thing is with the body type i want to serialize it as a string not an integer i mentioned this before just in case we rearrange stuff or we like i mean it's not that bad here these are kind of fixed right but in general it's it also makes it easier to read the actual yaml file if it's text and of course it's yaml so we're we're trying to make it easy to read easy to merge you know human readable and writable even so it's nice to kind of do that so let's add a little function probably up here and we'll call this so scd string um this will be a rigid body 2d uh body type i guess really body 2d body type 2 string body type body type and then i'll kind of do the same thing but this will be a from string because we'll obviously need that as well this will kind of just be rearranged body type string okay so how's this going to work well uh we'll just do a switch for this case so body type case static will return static dynamic kinematic uh we'll return an empty string in a set i don't know why this would happen um anyway memory corruption maybe catch some like memory corruption bugs all right so there you go static dynamic kinematic um and then uh for this though because they're strings and string comparisons and stuff we can't use switch statements so we'll just do uh if the body type string is static return this static dynamic kinematic return just static i guess and assert if it's for some reason neither of these okay easy so now uh we do two string for the serialization so it's going to be this body type or just type and then finally for the fixed rotation we'll just do the fixed rotation um that's good uh now we'll do the same thing for the box collide but again we can't save it's the stupidest thing i don't know how we didn't end up having a save button whatever this episode's already long anyway might as well just you know hope you guys are appreciating this series series um yeah lots of time it's okay i'm enjoying myself i guess uh box collider 2d box collider 2d component and then we have uh what do we even have in that we've got quite a lot of stuff so offset size so i don't think we have any um and again i've been through this in the live stream so when i say i don't think i'm i'm sure i'm just pretending that i don't know what i'm talking about i don't know why but uh we don't have any vector two kind of functions so if you look up we have vector three vector four we don't support kind of serializing vector twos so we'll add that in uh it's pretty simple we'll just get rid of z and we're done and then finally we'll do the same thing for like decoding them basically so you can just kind of convert note as well so two two get rid of this two get rid of this two right and that's it pretty simple so now we can serialize and deserialize vectors pretty easily um where was all this stuff uh offset size uh what else do we have so yeah density friction density friction restitution restitution threshold and i'll just copy that and that looks good okay that's it that's our box collider component done uh now obviously the deserializing stage so rigid body 2d component uh so rigid body 2d what do we have runtime body runtime body the the perfect thing to serialize so rigid body to the uh from string right so we're reading the string um um body type right dot as a city string then we convert it fixed rotation as bull that's it and then for the box collider 2d component box collider 2d so what do we have in there um make sure we do that so [Music] uh i guess offset is the first thing right glm vector have another vector which is the size and then the rest of floats starting with density friction restitution sure restitution threshold and restitution okay so in there we go looks like i'm falling asleep doing this card i don't know if you guys are like you know watching this on two times speed or just skipping it entirely i'll try and put chapters if i don't forget in the uh description so that they show up and then you can navigate this easier and skip this boring part but i think that's it so now we can save it kind of we just don't have a control s button but whatever we'll add we'll add that stuff next time because i think that it's going to be um it's going to be like you know we'll add all the scene functionality we'll add um being able to duplicate entities we'll have to save scene stuff so it'll make sense to kind of just do that all in one episode i think um okay uh what's going on with our editor oh i have this window on top for some reason so um physics 2d we're back to having nothing that's great let's try and build out our scene again so add rigid body add box collider we'll set this to be dynamic and then let's create our floor so i'll call this floor i'll add a sprite renderer a rigid body basically all the components have a camera um we'll make this static um i'll probably change the color to like orange because i like orange that's all we had in the other demo i'm fairly sure um make this like this um make this maybe a bit smaller um and then obviously make this yeah static and all that stuff now let's save this so save as and then we'll just overwrite physics 2d yes play there you go right so we have our kind of scene um we'll move this away obviously we can play with this we can also try and make it like longer you know it should work i guess because we obviously played with that um also i guess we'll check out the friction so if we make this rotated how how does it slide so it doesn't slide at the moment but if we lower the friction so 0.5 um let's make it like point one maybe then you can see it slides now right so the sliding's there let's rescue it uh and yeah i think that's pretty much it you guys probably get it don't need to sit here playing with it um i'll push this what's already on the dev branch but it'll also be in the main branch now so i will push this you guys can play with it at home if you like um but yeah uh bounciness is probably the last thing we didn't really touch since we did the changes but let's go to yeah let's just make it kind of bouncy i'll make it a bit bigger maybe no that's that's too big um density is probably also useful to play with makes a bit more crazy anyway um that's basically it right so uh i hope you enjoyed the episode you got to have it on a bit of an angle otherwise lol there you go fun times so that's how it works um again if we add duplicating functionality we'll play with this more next time we can set up entire maze um otherwise making these entities from scratch is really annoying um but yeah that's it so again i'll i'll save this physics 2d and then i'm going to load like pink cube right and then i'll go back to physics 2d and we have all of our stuff and it works right so that is it i hope you guys enjoyed this video this very long video of us doing 2d physics box 2d uh again not that difficult to implement i think um you know we went from scratch to having it in you know if you don't if you know what you what what you're doing it's quite quick but obviously if you're doing it for the first time it will take longer it took me longer the first time i did it obviously which was years ago but uh hopefully this was kind of beneficial to you guys not just if you're following along with hazel and you want to learn but also maybe for your own engines like that um again nothing really to it just need to know kind of what you're doing which the documentation is a perfect place for so don't skip the docs read the docs at least a little bit learn to read not just copy code um it's very it'll help you out in the long run i promise you but anyway i hope you guys enjoyed this video if you did please don't forget to hit the like button patreon.com the channel best way to help support this series get access to hazel uh 3d to the full version kind of hazel to the to to not just hazel 2d but you know all of the massive work that's gone into that um and obviously help support this series as well if there were no patreon supporting hazel the big version there would be no hazel little version or hazel 2d right or at least it wouldn't be at this stage um at all so thank you huge thank you to everyone for supporting this of course i'll be back with a live stream next thursday australian time as usual but until then have a great recipe day and i'll see you guys next time goodbye [Music] you
Info
Channel: The Cherno
Views: 28,688
Rating: 4.9560437 out of 5
Keywords: thecherno, thechernoproject, cherno, c++, programming, gamedev, game development, learn c++, c++ tutorial, game engine, how to make a game engine, game engine series, box2d, 2D physics, physics engine, 2d physics engine, box 2d
Id: B1nO5wbPbwg
Channel Id: undefined
Length: 81min 19sec (4879 seconds)
Published: Thu Sep 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.