#2 FPS Raycast Interactions: Let's Make a First Person Game in Unity!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
G'day everyone and welcome back in this  video we're going to set up a first person   interaction system this topic will be broken  up into two videos in part one we're going to   build the foundations of the system so that  we can design our interactions using code   and then in part two we're going to improve the  usability of our system by including a way to use   unity events when designing our interactions  before we begin i'd like to let you all know   that i've set up a discord server for anyone who  wants help with the topics covered in these videos   or any other kind of game dev help as well it's  still evolving as i figure out the best way to   use the platform but there's already a number of  super nice and helpful people in their discord   there's a link in the description  if you want to check that out   back in the unity project we created in part  one i've got two rooms here separated by a door   on one side of the door we've got our player  and on the other side of the door we have   a cake our goal for this video is to get this  door open and get our player to the cake so   we'll start by heading into our scripts folder and  creating a new c-sharp script called interactable   we'll open this up and the first thing  we want to do here is make this a public   abstract class so this is going to be a template  for us to create subclasses which will gain all   of the functionality of this interactable script  whether it's a button or a door a health pack or   an elephant if we want the player to interact with  it then it will need a script that inherits from   interactable now let's add a public string and  we'll call this prompt message and this is going   to be a message that is displayed to the player  when they're looking at an interactable now we can   get rid of start and update and replace that with  a protected virtual void function called interact   now we won't have any code written in this  function this is just a template function   to be overridden by our subclasses now just above  that we want to create a new public void function   called base interact inside here we  want to call our interact function   and this base interact function will  be called from our player script now this all might seem a little bit confusing  but what we've done here is something called   the template method pattern i've got a  link in the description if you want to   learn a little bit more about this so now  we'll save that we'll head back into unity   and we'll create a new c-sharp  script called player interact this script will contain all of the logic to  detect interactables and handle our player's input   so we'll drag this onto our player now and we'll  open it up in our editor now the first thing we   want to do here is have a reference to our camera  so private camera and we'll just call this cam   and because we already have our camera on  the player look script which is attached to   the same game object we can just assign this in  start to cam equals get component player look dot cam now in order for us to detect interactables  we're going to use a raycast there are three   parts that are needed to perform a raycast the  first part is the ray variable all array has   is an origin and a direction it's essentially  an invisible line that will detect colliders   the second part is a raycast hit variable  which we use to store some information about   the collision such as the distance from the origin  and some of the components of the hit game object   like the transform rigid body and collider  and the final part is the raycast function   and this is what we use to actually  check for collisions along the ray so now in update let's create a new ray and we'll  call this ray with a lowercase r this is equal to   a new ray first parameter is the origin so we  want the origin to be the camera dot transform   dot position and the second parameter is the  direction so camera dot transform dot forward so this has created a ray that will shoot  with an infinite distance but we can control   how far we want to draw this ray and how far we  want it to check for collisions so up the top   let's create a new private float and we'll call  this distance and we'll set this to equal three   and we also want to serialize this so that it's  visible in the inspector now we can debug our   array by typing debug dot draw array we'll pass  in the ray.origin and the ray dot direction   and we'll multiply this by distance so  we'll save that we'll head back into unity   and now if we go look at our player we test this  out we can see that we're drawing a ray from   the center of the camera and we can control  the distance of how far that ray will shoot alrighty so back in the script we'll  create a variable to store our raycast hit   and we'll call this hit info and the last  step is to use the raycast function to check   if we've actually hit anything so we'll type  physics.raycast and in here the first parameter   we'll pass is the ray that we just created and for  the second parameter we'll type in out hit info   and this out keyword means that the  function is going to return something here   in this case it is a raycast hit so when we type  this we are actually assigning a value to our hit   info variable then the next parameter is our  distance and then the last parameter will be   a layer mask so up the top we'll create a new  private layer mask we'll just call this mask   we'll serialize that and then we'll pass it into  our raycast function now the handy thing about the   raycast function is that it will return a boolean  so we can wrap this whole function inside of an if   statement so that all of the code inside the block  here will only run if our raycast hits something   so we'll save that we'll head back in unity and  we'll create a new layer for our interactables   up in the top right of the inspector we'll  go to layer and we'll add a new layer   i'll use layer 6 and i'll type in interactable  now in my scene i've got a cube here which is   a poor representation for a keypad but let's  just use our imagination and we'll assign it   to the layout interactable now we can click on our  player game object and we've got a drop down menu   with all of our different layers on here so we  want our raycast to be checking the interactable   layer so we can select that one there awesome now  back in the script the last thing we want to do   here is check if the game object actually  has an interactable component on it so if   hit info and keeping in mind this isn't the game  object itself it's just some information about the   collision so we'll get the collider dot get  component interactable is not equal to null then we can debug the hit info dot  collider dot get component interactable dot prompt message alrighty so we've made  our base interactable script and we've   given the player a way to detect those  scripts but there's still a way off from   getting the cake so now let's get the keypad  working we'll save that head back into unity and we'll create a new folder called interactables in this folder we're going to put all of  our scripts that inherit from the base class   like our keypads and elephants so we'll  create a new c-sharp script called keypad   we'll drag it onto our keypad game object and  we'll pop it into our interactables folder now we'll open up the script and first up we want  to inherit from interactable we could probably get   rid of start and update here but i'll just leave  them in case we need them and down the bottom   of the script we'll type protected override  and we want to override the interact function and this function is where we will design  our interaction using code if we want to   change colors of something play an animation  destroy an object then we will do it in here   all i'm going to do for now is just  debug a message saying interacted with gameobject.name alrighty so if we head back into unity  and look at our keypad in the inspector   we can see that this is now inheriting  the prompt message we don't actually   have a variable for this on our keypad class  we're getting that from our interactable class   so i'm going to set this to  use keypad and i'll hit play if we walk up to the keypad we get a debug message  saying use keypad so our next step is to display   the message on screen using text is a nice  and clear way of giving feedback to the player   but there's lots of different ways that we could  do this we could update the crosshair display a   button prompt outline the object and you may have  noticed a lot of games will display their prompts   in world space where the text hovers around the  object itself if there's any interest on how to   set up world space prompts or any other types of  feedback i might create a video for that later on   in the series but for now let's just stick to  displaying prompts in the center of the screen   so over in the hierarchy we'll go create ui and  we'll create a new text mesh i'm going to be using   text mesh pro and if you don't have that installed  you can install it using the package manager   or you can just use the built-in unity  text i prefer text mesh as it's a lot   cleaner and has a bunch more options  so we'll rename this to prompt text so unity has parented our prompt text under a  canvas and it's also added another game object   in the hierarchy called event system on here we've  got a standalone input module which allows us to   navigate ui however we've got this big red stop  sign here and what all of this text here is saying   is that this component is designed for the old  input manager so thankfully unity provides us   with a nice way to fix this we'll click this  button here and this will replace the component   with one that is compatible with the new input  system now unity has linked a example action   asset that comes imported with the input system  so if we click on it we'll see that it's buried   in the packages folder and it's kind of annoying  to get to so in order to keep things a bit more   organized we're going to take all of the ui  actions from this asset and copy them into   our player input asset that we made in the last  video so we'll right click we'll copy go over   into our player input actions then right click  on our on foot action and we'll paste it in there   now we can close the default input actions and  before we do anything else make sure that we save   the asset now we'll navigate over to our input  folder and we'll click on the event system and   we can drag our player input asset over here onto  the event system and that will keep all of these   bindings here linked if you didn't save the  asset before dragging this file on then all   of these will be cleared out and you would have to  manually assign each one so in our ui action map   there's some things in this asset that we don't  need and some things that we might need to add but   for now this will do the job now before i forget  i'm just going to set the text to be in the lower   third of the center of the screen and then i'm  going to set the alignment to be center as well   alrighty and let's create a  crosshair so we'll go create ui image   we'll call this crosshair set it to be zero  on the x and the y axis we'll give it a width   and height of five and we'll set it to be just  the circle heading back into the scripts folder let's create a new script called player ui   we'll drag this onto our player and in fact  we've probably got enough scripts here that we   could create a new folder for all of our player  scripts so we'll drag all of those into there   now let's open up our player ui script at the  top we want to make sure that we're using tm pro and we'll create a private text mesh ugui  and we'll call this prompt text we'll put the   serialized field header just above it and we'll  replace our update function with a public void   update text this function will take a string as  the parameter and we'll call this prompt message   now in this function we want to set prompt  text dot text to equal prompt message   now we'll save that we'll head back  into our player interact script   we want to have a private  property for our player ui script   call this playerui and we'll assign this in start  player ui is equal to get component player ui and if we head down into our update  function we can replace this debug.log   with player dot update text and one  final thing that we want to do is   make sure that the message gets cleared  when we're not looking at an interactable   so at the very top of update we want to set  playerui dot update text choose string dot empty   now we'll save that and head back into unity and  we'll drag our prompt text onto our player ui   now if we hit play our message is cleared   automatically and if we go  up and look at the keypad we can see that it pops up with use keypad so now the next step is to  actually interact with it   so we'll stop playing and over in our action  editor we'll open up our on foot action   map we'll create a new action by hitting the  plus button and we'll rename this to interact   i'm going to give this action two bindings the  first binding is going to be set to e on the   keyboard and the second binding is going  to be set to button west on the gamepad   remember to save our asset and head back into the  player interact script and we'll set up the player   input for interaction so we need a reference  to our input manager private input manager we'll assign it in start and then down in update we want to add in if input  manager dot on foot dot interact dot triggered   which works in the same way that input.getkeydown  works from the old input manager so anytime our   player changes the state of the interact action  then this dot triggered callback will become true   now we could type in hitinfo.collider.getcomponent  again but we're going to be using this multiple   times here so let's store this in a temp  variable we'll create a new interactable   we'll just call this interactable as equal then  we can just cut this section out here paste   up the top now we've got direct access to our  interactable component using this variable here   we can type in interactable dot prompt message  instead so a little bit sidetracked but let's   just recap we're raycasting to the center of the  screen we're checking to see if our game object   has an interactable component if it does then  we're storing that interactable in a variable   and then we're updating our on-screen text so back  to when our player is triggering the interaction   inside the if statement we want  to call interactable.base interact   and remember inside this base interact function  we are then calling the interact function   so because the interactable object we're looking  at is a keypad this will then run the interact   function in our keypad script okay so that's  all we need to do here let's save our script   head over into unity and test it out and now if  we walk up to the keypad and interact with it   we get a debug message now that's  a step in the right direction   but our player still doesn't have any cake so our  last step is to get the keypad to open the door   let's quickly create the animations for the  door now we'll run through how the door is   set up first we've got two halves of the door  here and they're just cubes with box colliders   these two halves of the door are parented  to a game object that we're going to be   adding an animation to so we'll go up to window  animation and we'll open up the animation window   we'll dock it down here next to the console and  with the door selected we'll hit this create   animation button we'll stick it  in a new folder called animations and we'll call this closed now to  animate the door we'll hit add property   we'll open up door 1 and door 2. we'll  open up both the transforms for these   and we'll shift click on the plus  buttons next to the position there   and we'll delete the keyframes at the end of  the animation now we can click this arrow here   and we'll go create new clip and we'll call  this animation open we'll do the same thing   add property door 1.2 transform and add the  positions we'll delete the last keyframe and here we want to hit the recording  button and we want to open these doors alrighty so those are our two animations  we've got closed and we've got open now we'll head up to window animation  and we'll open up the animator window   in here we've got both of those animations that  we just created we've got our closed state and our   open state so we'll need a parameter to control  the flow of these two states so next to layers   we've got parameters and we can add a new one  by hitting the plus button up here and we want   to make a new ball we'll call this is open now  we can make transitions between these two states   so when transitioning to open we want  to check to see if the bull is true   and then when transitioning to closed  we want to check to see if it is false now we can select both of these  and we want to untick has exit time now if we hit play we can kind of get an idea  of what's happening here right now we're playing   the closed animation and if we check this ball  the doors open and the player gets their very   first sight of cake but that's cheating so we'll  stop there we'll head back into our keypad script and at the top we want to have a private  game object for our door and we'll add   the serialized field header to  that and we want a private bull   or door open now down in the interact  function we'll get rid of our debug message   and the first thing we want to do  is toggle our door open variable so   door open is equal to not door open so  that'll just toggle between true and false   next we want to get the animator component on  our door so door dot get component animator dot set bool and the first parameter we're  going to pass in is the name of the boolean   on the animator so is open and then the second  is the value that we want to pass in so we can   just pass in true or false here but we want to  pass in door open awesome so we'll save that   we'll head back into unity we'll make sure that  we drag our door onto our keypad script and now if   we test it out so we'll walk over to the door we  get our message use keypad if we press the e key   the door opens now player finally gets their cake   and that's everything that we're going to be  covering in this video now the next step is to   go off and create tons of interactables that will  make our game worlds feel alive i'll add the three   scripts from the examples at the beginning of  the video here however some of them will need   a bit of setting up to work correctly but that  should be a good basis for everyone to get started   thank you so much for watching i hope you enjoyed  if you did please consider liking and subscribing   in the next video we're going to expand  this system and incorporate the use of   unity events with our interactables we'll  go into some basic editor scripting to keep   our design nice and clean so stay  tuned for that one bye for now you
Info
Channel: Natty GameDev
Views: 177,925
Rating: undefined out of 5
Keywords: create a game in unity, creating a survival game in unity, horror games interaction, first person, 3d game design unity, survival game in unity, fps interaction tutorial, interaction, unity 5 next gen tutorials, how to make fps movement, unity character controller, brackeys create a game, raycasts in unity, picking up objects in unity, unity fps movement tutorial, beginner fps movement unity, raycasts, walking simulator unity, c# programming, unity 5 tutorials
Id: gPPGnpV1Y1c
Channel Id: undefined
Length: 22min 3sec (1323 seconds)
Published: Tue Feb 22 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.