Spawn Objects Like a Commercial Game: NEVER Spawn Objects Into a Wall Ever Again (Unity Tutorial)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey I'm Brandon if you've been learning game development on YouTube for any length of time you will inevitably end up asking the question how is it handled in a commercial game a lot of YouTube tutorials end up doing things very quickly or doing things just good enough but they end up having this kind of game Jam feel to them and if you're anything like me you want to know how to take that mechanic to the next level how do actual real games handle these situations in samurado the commercial game that my wife and I are working on right now I just finished working through a problem where I needed to be able to spawn chests and enemies and various other things into the game but I need them to 100 of the time never spawn on top of the player on top of other enemies or into the walls or on top of other items so you are going to learn how to do that right now ready let's go so I kept this scene very simple to keep things on point what I'm aiming to do is when I walk through this opening and enter this room we'll spawn a few enemies into the room and the rule is going to be they cannot spawn on top of other enemies or in the wall or on the player and they have to spawn inside this room so you can see I've just got this object which holds a few different box colliders and we're combining them into one polygon collider with this composite collider here and first really quick we need to be able to detect when the player enters this room so that we know when to spawn enemies in and you could set this up in a dozen different ways it really depends on your design needs right do you have some high level manager controlling what enemies could spawn into a room each time you enter the room or do you want the control down at the room level you could use scriptable objects to hold the spawn info so you could have lots of like pre-made iterations that you can swap in and out for me with this I want to keep it simple so I'm fine to just have this at the room level and just have the room itself decide what enemies can spawn in you actually have a lot of control that way so first I'm going to create an empty game object called entrance inside of this room walls object and let's add a box collider 2D and set it to trigger and place that at the entrance of the room and let's create a script called room detection and add it to the entrance game object so first we're going to do this in an on trigger exit 2D function and I don't want to search for a tag each time something collides with this trigger so let's just store our player once in the start function and now that way we can check if the Collision game object is the player game object and if it is we want to make sure we're exiting from the correct side right I don't want to walk on here and exit from the left and then have things spawn into the room on the right that makes no sense so let's grab a reference to the collider on this game object and use that to calculate a Direction the formula to calculate a direction is simply destination minus origin normalized you're going to want to get comfortable with that formula you will use it a lot when making games and in this case destination would be the player's transform because the origin is definitely this game object's Collider okay so now we just check is the x of the exit Direction greater than zero and if it is then that means we did exit from the right and we should spawn in some enemies now there are two pieces of information we're going to need to pass in we want an array of enemies and a spawnable area depending on your project this could be a box collider a tile map collider a composite collider but it doesn't matter the generic collider 2D will work for all of those so let's just plug in a debug.log statement to make sure that that's working so we hit it nothing happens we exit from the left nothing happens we exit from the right there you go cool so now let's handle actually spawning the enemies in create an empty game object called enemy spawn manager and let's also create a script called enemy spawn manager and attach it to that game object first let's make this a Singleton and we're going to want three functions in this script a spawn enemies function which is the one we'll actually call from the room detection script and remember I said we'd need to pass in two pieces of information let's add those in as arguments so we'll pass in a collider 2D for the spawnable area and an array of game objects for the enemies we also need a get random spawn position function and let's pass in the spawnable area collider and finally a get random point in collider function which will also take in a spawnable area collider as well as a float which we'll use as an offset by setting the float within the argument we've given it a default value which means when we call this function we can either pass in a new Float by typing in a number or if we type nothing for this function for the second argument it'll use the default value so the first function relies on the second function and the second function relies on the third so let's actually work from the bottom up this function is just to get a random Point inside of a collider and so you can better visualize that let's go ahead and set that up now create an empty game object as a child of room walls called spawn area and will attach a trigger box Collider now let's make it take up the whole room okay now let's go ahead and assign that in the room detection script as well as our enemies by the way if you want access to the art assets that you see in this project there is a link Down Below in the description they are free you can use them commercially or however way you want I'm going to use the enemies from that pack but also my patrons get access to the GitHub source files so if you want access to this project or get early access to our videos or monthly Alpha builds of our commercial games you can sign up to support us on patreon okay but there we go everything is assigned now so back in our script let's grab the bounds from that Collider and basically I want to find what the new bounds are with this offset included you can think of it like a margin around the room it's going to be the minimum of the X plus the offset and the minimum of the Y plus the offset as well as the max of the x minus the offset and the max of the Y minus the offset so you're going to end up with a rectangle that looks a little bit more like this technically speaking and yes I could have just reshaped this collider obviously but I'm showing you the offset method in case you're working with a tile map collider or something like that where you might not have such fine control over the size of the collider it can be really useful to pick an offset right into the function plus this way if you just line up the edges exactly to the edge of the room and it works in one room then you'll know that it works in every room automatically okay so next we'll pick a random X position and a random y position and return a vector two with those random coordinates next are random spawn position let's set up a spawn position as well as a Bool called is spawn POS valid so the best way to handle this is to use a while loop and have Unity try certain spawn positions and see if they're valid and if they are it'll spawn the enemy there and if it's not it's going to try again so just in case right we we don't want to create an infinite Loop and freeze Unity so let's set a nice and high Max attempts that way at least it'll have a Max and it can't freeze and now we're going to use the physics layers for our checks and if you only have one layer to check then it's pretty easy to set up that way you can set your layer to not spawn on and say while our spawn POS valid is false and our attempt counter is less than our max number of attempts right so we still have attempts left and we haven't found a valid spawn position yet then we're going to set our spawn position to our get random point in collider and now we'll create a little circle using physics 2D and return an array of all the colliders within that little circle the radius of that circle is going to depend on the size of your enemies and we could pass in the bounds of our enemy colliders and size it that way but that's kind of unnecessary unless the enemies you want to spawn in like very wildly in size the easier thing to do would be to quickly just add a circle collider to one of our enemies and just see what the radius is and we can round that to the nearest whole number and pass it into the function this way is just a little bit more performant and just remember to remove the circle collider afterwards and create this bull called is invalid collision and we'll say for every single collider inside this array does its physics layer equal our layer to not spawn on then we'll say this is an invalid collision and break out of the for each Loop to continue on with the while loop now if our is invalid Collision is still false meaning none of the colliders found within this circle are on the layer we don't want stuff to spawn on then we found a valid spawn position and of course don't forget to increment our attempt counter now if after the while loop is finished there's still no valid spawn position let's log a warning and finally return the spawn position because this is not a void this is a vector 2 function so it needs a return type and this function is short I promise we'll say for each of the enemies within this enemy's array we'll get a random spawn position and instantiate one in using the current enemy and the spawn position from the function that we just finished setting up cool now let's actually call that function in our room detection passing in the spawnable area and the enemies to spawn array Let's test really quick and don't forget to set your spawn area to trigger cool so you can see they're spawning in and they are not spawning on the walls and actually just to prove this a little bit more let's actually go ahead and resize the collider to take up the entire room including the walls and I don't want to have to keep on walking in and out of the room a bunch of times so really quick I'm just going to check if I pressed the E key and if I did then I'll spawn in the enemies but there see no enemies spawning in the walls but they can spawn on top of each other and on the player which is no good so let's comment this out and this for each Loop because we need to handle this differently actually let's just delete it we want direct control over which layers we do not want the enemies spawning on so let's set up a layer mask for that and down here what we'll do instead is another for each Loop checking every collider within the colliders array from our overlap Circle all and we're going to pass in this if statement I am told that this is called a bitwise operation and I made a note about this a while back and I often will use it but I I'm not gonna lie I do not understand this code I even asked chat gbt to break it down for me twice and I still do not understand it I know that there is some genius watching this video right now and if you are out there and you're watching can you please go into the comments and explain like what the heck this actually means please comment down below so that we can all learn something from this video all I know is that this will return true if the collider is within one of the layer mask layers that we set so that would mean that this is an invalid collision and we can break out of this to keep on trying okay all right so now in the inspector let's actually set up all the layers my enemies are on a layer called attackable so we do not want our enemies spawning on attackable or the ground or the walls or the player let's give this a test all right there you can see that they are only spawning in valid places and eventually when they run out of room it's just going to throw this warning instead that's all I got I hope you enjoyed thank you for watching like this video if you liked don't if you didn't and I will see you next week guys but I want to give a very special thank you to all of our Hall of Fame patrons Jacob yondak zonder Kessler Darren perine throbbing wind Fontaine Wade couch and Christopher Nichols as well as our Early Access patrons xioma can wait Mason Crow Mr D and audoo games if you choose to support us on patreon you can get early access to all of our YouTube videos monthly Alpha builds and more
Info
Channel: Sasquatch B Studios
Views: 7,502
Rating: undefined out of 5
Keywords: unity, unity2d, unity tutorial, sasquatch b, unity beginner tutorial, object spawning in unity, game development tips, unity advanced tutorials, unity game creation, unity spawn objects in area, unity spawn objects within a collider, unity spawn objects not on player, unity spawn objects and avoid collisions, unity spawn objects and avoid player, unity spawn objects and avoid enemies, unity spawn enemies not on top of other enemies, unity enemy wave spawner, unity game mechanics
Id: ieuC39qv4x4
Channel Id: undefined
Length: 11min 53sec (713 seconds)
Published: Thu Jun 08 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.