How to Add a Field of View for Your Enemies [Unity Tutorial]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi guys it's mike here from com3 interactive welcome back to the channel so what am i teaching you today then what i'm going to show you to do is a very simple but very effective field of view now you can call it field of view corner view whatever you like it's exactly the same and what i'm going to be doing is using this red capsule as the enemy the green capsule as the player and we're also going to take into consideration obstacles such as walls and we're also going to make a nifty little gizmo to show us exactly where our field of view is and the range so if i just go ahead and play this you'll see exactly what this does pop over to scene view and as we can see we have a yellow field of vision so anything within that is what our enemy can see and then the white ring is a range so how far out field of view stretches now currently our enemy can't see our player because he's behind a wall if we were to move that we see we have this green line now which always points at the player until we exit the field of view really cool and the way this is set up we're going to return a boolean value whether or not we can see the player and i'm going to leave that up to you as to what you do when you see the player be it the game's over or the enemy will chase the player that's down to you so i'm going to go ahead i'm going to clear down the project of any scripts and we're going to build this from scratch and i promise you it will not take long but before we start i just want to thank gigatank3000 for sponsoring this video i've got his links down in the description below go check him out on twitter go check out his website keep up to date with everything that he's doing and i also want to thank everybody supporting me over on patreon you guys are fantastic that's brandon zill steve uk love you guys okay so i've cleared down my scripts and a few other things that we'll get to later on in the tutorial but first of all we're going to create a c-sharp script and we're going to call it field of view what a surprise now we'll open it up in visual studio and we're going to need a few variables in here we're going to need the actual radius in which our view can be seen and we're also going to want the angle in which our view can be seen as well so let's just go ahead and create some public floats i'm going to call one radius and i'm going to call the other angle we're also going to want to grab a reference to a player or a reference to the object that you're trying to search for so we'll just create a public game object and we'll call that player ref next we're going to set up the infrastructure for dealing with the targets and the actual obstructions such as the walls and we're going to do this using layers so we can actually set up layer masks as a drop down inside of the inspector so we can just toggle on and off which layers we want to be affected for certain things now that may be a little bit confusing but you'll see exactly what that means later on in the tutorial for now all we're going to do we're going to put in again two more public layer masks and these are going to be our target mask and we're going to need one more and that's going to be our mask then the final variable that we need is the boolean as to whether or not we can see the player okay so we've got all our variables let's cache our player reference from the start so we'll create a start method and we're just going to set player ref equal to gameobject dot find object with find game object with tag i'm going to search for the player tag simple as that you must have done that before next we're going to want to start looking for a player and because this can actually get quite performance heavy i'm going to do this inside of a core routine with a delayed offset so instead of doing all these calculations every frame i'm gonna make it so we only do it five times every second the player will not notice that but it just makes your game a little bit more performant which we love so let's start by creating this core routine so i'm going to create private i e numerator and i'm just going to call this fov routine we'll declare our actual uh delay in here so we'll just set delay equal to 0.2 f and then we're going to start an infinite loop now don't worry we're inside of a call routine this will not crash your game if done correctly so basically all we're going to do we're going to start this core routine and we don't want it to stop until the object is destroyed or you could even have a variable to actually tell the engine that you do want to search or you don't want to search currently we're just going to permanently search for the player next we're going to need to set up a weight for seconds so we can actually delay our search by that amount of seconds so we'll set wait for seconds wait equals new wait for seconds and we'll pass in our delay or you could even just pass in 0.2 there and that's what we'll do now in case you're not familiar with core routines wait for seconds will only work inside of a core routine and if you want a little bit more information on core routines i do plan on getting a tutorial out soon that covers them in a lot more detail so make sure you subscribe for when that video comes out so basically we want to wait that amount of seconds before we check for the player so we can yield return and we'll just return the weight which is 0.2 seconds and then we'll actually do our searching so we'll create a method called field of view check and we also want to start that field of view routine inside of the start method so we'll do start call routine and pass in field of view perfect so that's the basics dom software now we just need to actually check for the player and we're going to use ray casting and sphere casting so the first thing we'll do we'll set up a collider array because we don't care what type of collider we're going to find we just know that it is going to be of type collider and i'm just going to call this range checks because this is going to be what's actually looking for a player and we're going to set that equal to physics dot overlap sphere and then we need to set up all the parameters for this sphere so first of all it's the position which is going to be our transform dot position so we're starting this sphere from the center position of our enemy we're going to use a radius because we need a radius and then lastly this is where we can use a layer mask so put really simply the layer mask all it's going to do is going to look on that layer in particular to find these objects so we're not going to be searching every single object in our scene only objects that are on that specific layer mask and the layer mask that we're going to be using is our target mask and for this instance the only object that's going to be on that target mask layer is our player so now we've put our range checks out there let's have a look if we found anything so to do that we'll check if our rangechecks.length is not equal to zero so it's anything above zero we found something on that layer so let's get the transformer that so we'll cache a transform we'll call that a target and we'll set that equal to uh range check and we'll get the first instance in that array and then get its transform now the reason we're doing this is because sphere or overlap sphere returns an array and we know that there's only our player on this layer so we only ever want to get the first one if you were looking for multiple objects or there's going to be multiple objects in your target mask layer then you just have to do a for loop over every one of your range checks and then every one that it finds if that's the one that you're interested in then you'd continue with the rest of the logic that we're going to do in just a second next we want to find the direction from where our enemy's looking to where our target is our player is and that's going to be in a vector 3. i'm going to call that direction to target i'm going to set that equal to our target dot position minus our current enemy's transform dot position and we're gonna normalize that just to get the value between zero and one now that we've got that we can actually start checking for the angle so here we'll do if vector three dot angle so here we need a from position in our two position so we're going to pass in transform dot position our enemy's current position and then uh direction to target i'm going to check if that angle returned is less than the view angle that we want divided by two now we're going to divide it by two because if you think about it if the enemy is facing forwards you've got half of the angle to the left and half to the right so we want to narrow that down by half so we can actually do a detailed angle check so before we go into that if this angle check fails then the enemy the player is definitely not within our eyesight so we can just set can see player to false there that's all we need but if the player is within the angle then we want to make sure that our distance to our target is close enough to actually trigger that can see player so we're going to set a float and we're going to call this distance to target and this one's really simple it's just going to be vector 3 dot distance i'm going to pass in our enemies current transform.position and then uh target's position so sulfur we've managed to get the direction to the target the angle in which we should be looking and the distance that our target is away from our current view angle so after all that we can actually do the final rare cast which is going to be the one that determines whether or not yes we can see the player no we can't so if physics dot rarecast we're gonna start our array again at uh enemies current position so transform.position then we're going to pass in our direction to target i'm going to pass in our distance to target and finally we want to pass in our obstruction mask so we'll just break that down really quickly we're going to start a rare cast from the center of our enemy we're going to aim that ray cast towards our player we're going to limit that ray cast to the distance that our target is aware and we're also going to stop the rare cast if it hits anything in our obstruction mask now that's key for when we're dealing with the walls and we've also got the exclamation mark right at the very start of this now the reason we've got that is because we want to do the positive check first so this will mean if this fails so if we're not hitting the obstruction mask then we can see our player so we can set currency player equal to true or else can see player equals false tidy that up a bit that look messy and then the one last thing we need to do we need to make sure that if our range check fails so a player isn't within range of the enemy at all we'll just check if can see player was set to true then can see player is false and the reason we do that is if you were previously in the view of the enemy and you're no longer in view of the enemy we want to make sure that we set can see player to false so that should be our field of view script completed if we select our enemy throw the field of view script on here we can see we have all of our variables now i'm just going to make this a little bit nicer so i'm going to pop back over into my script and i'm going to add a few attributes up here so the main one that i want is the angle can never go past 360 degrees we know this so we'll limit it to 360 degrees by putting a range attribute in there if we save that and pop back we should see angle is now a slider perfect but we're not actually getting any of this information on yet once we hook everything up this would work but we don't have any visual cue that this is working so we're going to create an editor script that extends our field of view and it'll actually show us some gizmos on screen now because this is an editor script we need to put this in the editor folder i've covered this in other tutorials before the editor folder is a reserved folder that won't be compiled when you build your game which is exactly what we need because we don't want this going into the final product so i'm going to create a new c sharp script in there and i'm going to call it field of view editor just to keep everything nice and neat and tidy keep all the naming conventions so this is going to be a quick overview if you do want an actual in-depth tutorial on creating your own editors then let me know in the comments below because i would love to do one of those but it's whether or not that would be useful for you guys so we're going to blitz through this there's a lot of maths involved i'm crap at maths and i've got all the values pre-worked out on my second monitor so the first thing we want to do we will not be using unity editor next this isn't going to inherit from monobehaviour it's going to inherit from editor and we also want to make this a custom editor for the type of field of view so now whenever a field of view is active this editor will start running and we don't need to start an update but we do need on scene gui so the first thing we're going to do we're going to set up a field of view object we'll call that f4v and we'll set that equal to the target of this editor and we need to cast that to field of view next we'll just do a little bit of styling so we'll set the color of our handles which are going to be the field of view arc and the radius as well so first of all we'll do the radius so we'll set handles dot color equal to color dot white and we'll draw in that radius another way that we do that we'll just again use handles dot draw wire arc and this takes in the parameters that you'd find on pretty much any sphere in unity which is going to be a field of view object dot transform dot position we're gonna give it a normal value of vector three dot up we're gonna give it a from value of vector three dot forward we want this to be a full 360 degree angle and then the radius we're going to put in as a field of view dot radius so now if we were to play the game here we'll play the game we'll go into the scene view we don't see anything yet but that's because our radius is still set to zero if we up that to seven for example we see we now have the radius in which uh enemy can see a player so we'll jump back and we'll start adding in the actual viewing angle so here we're going to need to create two vector3s one for the leftmost side of the angle and one for the right side of the angle but just to do that i'm going to create a separate function just at the bottom here i'm just going to return a vector3 and that's gonna get the direction from angle and this is where all that horrible maths came into play that took a while to figure out but no it's all ready for you so the first property that we need to pass in is the euler y value and that's going to be the euler y value of our enemy next we need another floor and that's going to be the angle in degrees now we want to add that euler y to our angles in degrees so the angle in degrees plus equal to our euler y and then we'll return a new vector 3 which is math f dot sine and into that we're going to pass in our angle in degrees multiplied by math f dot deg 2 rad degree to radius or radians rather told you i hate maths next we'll just pass in the y as 0 and then the z is going to be math f dot cos and then in here we're going to pass in angle in degrees again times by math f dot deg2 rad so now that we can actually get the viewing angle from a direction we can create two vector threes which is going to be vector three view angle one i'm gonna set that equal to a direction from angle we'll pass in a field of views transform dot euler angles dot y negative fov dot angle because remember if the enemy is facing perfectly straight then we're going to want half of the viewing angle on the left and half on the right so we'll pass in the negative angle divide that by 2 and then we can just copy this for the right side of the angle so we'll change that to view angle 2 direction from angle exactly the same apart from we'll pass in the positive angle from our field of view object now we can actually draw those in as gizmos so we'll change the color we'll set handles dot color equal to color dot yellow this time just so we can actually see him as a different object we'll draw in our handles by doing draw line and we want to draw this line from our field of views transform.position so again the center of our field of view object and then we want to limit that by passing in again uh field of views dot transform dot position we're gonna add in view angle one and then we're gonna times it by a field of views radius so that should limit that yellow line from going past of past our radius and if we just copy and paste that again we can draw in angle two for the right hand side so let's save that we'll pop back over into unity we don't see anything other than a straight line which obviously isn't right and that's because we haven't set the angle in our field of view script if we increase this we see we get the corner view that enemy can have and you can set that to whatever you like i'm just going to keep that at about 100. finally we want some indication of whether or not the enemy can see the player um again really simple to do inside of a unseen gui in our editor script we can check if a field of view object can see the player which we've set up inside here that's our actual currency player in this function then again we're going to change the color so we can see it a little bit more clearly we'll set this to green this time and we'll draw one more line so that'll be handles dot draw line again from the center of our field of view object and we're going to go towards a player reference that again we have in our field of view object so that'll be fov dot player f dot transform dot position simple as that now the final thing that we need to do is set up our target masks so if we come up here to the layer tab at the top add a new layer we're going to add in a target layer and an obstruction layer so first of all we'll set our player as the target hop back over to our enemy object and set the target mask to be target next we want our obstruction mask to be obstruction and we'll go ahead and hit play and we'll see what happens absolutely nothing what have i done wrong ah that's it when we're dealing with the angle we shouldn't be using transform.position we should be using transform dot forward it's all these transformed up positions it got me messed up right so now this should work let's go ahead and play and there we go we can see a green line that looks towards the player whenever they're in range and only when we're within this viewing angle but we can see that it still goes through the wall and the way that we've set this up it's going to be nice and simple how we do this we select our wall put it on the obstruction layer and that's it so now our enemy shouldn't be able to see the player through the wall we don't have the green line but we're definitely within range we're in our angle we come round and bang there we go spotted him and away and no wait no i can't move the player around or else we can't see our field of view but yeah if we move that wall out of the way as well we can see that we just have this perfect field of view and what i'm going to do i'm going to put this up on my github page i've been kind of neglecting the github page recently i keep forgetting to actually put the chord up there that i write but this i think is an extremely useful script so if you want to download it dissect it change it a little bit however you want please feel free i'll put the link down in the description below but that's about all i've got for you today so i'll see you again soon thanks for watching guys if you like the content remember to subscribe to the channel for weekly unity tutorials
Info
Channel: Comp-3 Interactive
Views: 8,917
Rating: 4.9820628 out of 5
Keywords: comp3, comp3interactive, unity, unity5, unity3d, unity2d, tutorial, game, development, dev, introduction, program, programming, code, coding, csharp, c sharp, c#, games, develop, 3d, 2d, artist, programmer, editor, extension, easy, beginner, advanced, professional, how to make a game, how to make games, game development, how to use unity, brackeys, comp-3 interactive, unity 2d, unity 3d, how to make, how to do, make money with games, field of view, field of vision, fov, line of sight, cone of view, view cone
Id: j1-OyLo77ss
Channel Id: undefined
Length: 23min 45sec (1425 seconds)
Published: Fri Feb 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.