Unity Interaction Tutorial | How To Interact With Any Game Object (Open Chests & Doors etc)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to today's video in today's video i'm going to show you how we can make this interaction system that has a billboarded ui and responds to different objects in the world and then when we press the e key it's going to interact with the object um currently i've just got it set up so it'll debug.log something um if i press e in front of this chest we can see that it says opening chest if i press e on this door it says no key found because it's checking the player's inventory for a key if i using dev cheat mode if i press q that gives me a key then i can go back over to the door press e and it says opening the door because we found the key so i'm gonna go through this in three stages feel free to tap out in sort of any stage or follow the time stamps if you want to just jump to kind of one different stage but let's just jump straight into the video so as you can see here i'm in unity 2020.3 and i'm just using the third person template as a bit of a starting point so what i'm going to do is i'm going to go into the scripts folder here and let's create a new folder and we'll call this a interaction system and the first thing i'm going to do is i'm going to make a new script in here and i'm just going to call this the interactor this is going to be a component that can sit on our main um layer object i'm going to open up this script in my id which is rider okay so we've got our interactor component here and i'm just going to get rid of the start and update method for now and we will go back and probably implement at least update um but first things first let's just create uh some serialized fields so i'm going to do a serialized field and this will be a private transform and we'll call this uh interaction point we'll do serialized field private float and this can be the interaction point radius and i'll set that equal to 0.5 f just by default and we will make a serialized field private layer mask and this can be called the interactable mask so these are our serialized fields which we can set up in the inspector then we need some other private fields that we don't need to see in the inspector um what we can do is we can do a private read only a collider array and we'll say uh colliders and we'll set this equal to a new collider array of um we'll say three we don't want this is going to be kind of how many things we're going to search for and once once this collider is full we won't be looking for any more so for what we're doing we're going to be using the um overlap sphere uh the non-allocated version which reduces the amount of garbage the garbage collector needs to get up and it's just a bit more um performant i think it is slightly slower to do it this way but so it depends do you want like pure speed or like memory performance um and then i'm gonna make a um i'm gonna serialize this uh but it doesn't need to be serialized but this is just so we can see it in the inspector i'm gonna say uh private in um num bound and this is gonna be the number of colliders that we've actually found that um are on this interactable mask so let's go into our update function and i'm just gonna set numfound equal to physics dot overlap sphere non-alloc and the position is going to be our interact point dot position the radius will be our interaction point radius the collider array which is going to be the results is our colliders array then we're going to pass in our interactable mask so this is going to find everything within at this position within this radius that is part of the interactable layer mask and it will put them and it will just put three because that's the size of our array it will just fill this colliders array with what it finds and because we're passing that in by reference that will just do that and then this actually returns um an int so this is the it'll return the number of things that it's found within this uh function so but for now let's just leave that there and let's try and let's get the rest of it set up and make sure this is all working before we try and do something with that i'm just gonna i always forget to zoom in so i'm just gonna zoom in here so you can see this uh nice and big so this is the code for that i'll try and remember to zoom everything else in so let's go back to our project and let's just set up the um layer character so i'm just going to collapse all of these default scripts that come with it so on our player armature i'm going to drag in our new interactor component and we need to um build these in so let's right click create a empty and we'll call this the interaction point and i'm just going to zoom into this let's bring it forward just slightly just so it's in front of the player episode slightly uh maybe to about there and then let's go back to our armature and drag our interaction point into our transform or the interactable mask we we're gonna need to make a new um layer so let's go up to layers we'll add layer into number six and we'll just say um interact so this is our new um interactable layer and we're not going to select it for our player but we can see that there which means now in our interactable mask we can choose interactable so this is me looking for any objects that are in the interactable mask and we can kind of see that working now if i make a new 3d object cube let's put that there um let's just put that on the ground over here so it's got a box collider on it which is great because it needs a collider for this um script to detect it for the physics script and let's just put that on the interactable layer now before we go and play the game i'm just going to come back to our interactor script and i'm going to do a on draw gizmos and in here i'm just going to say gizmos dot red sorry gizmos dot color is equal to color dot red and then we'll draw a wire sphere so dart draw is sphere and we're going to do this at the interact point dot position and with a radius of interaction point radius if we just save that and go back to our project so you see now this is our interaction point so this is what's going to be doing the overlapping and we could even maybe bring the radius down slightly so let's just do 0.25 and we've got this number found here when we hit play that should stay at zero and you see that as we walk forward and we're now this um our red interaction point sphere is overlapping this cube which is on the interactable layer we've now found one thing that is interactable if we back off we've got zero things found and then number found one again and we can you know we can duplicate this cube so ctrl d duplicate uh bring it over and then if we go over to the position here you see that number found two because this is overlapping both cubes so that's working uh nicely so the next thing i'm gonna make is i'm gonna make a interface so i'm gonna create a c sharp script i'm gonna call this i interactable and if you don't know what an interface is i really suggest um doing a bit more reading on it but the very basics of what a um interface is is it's just a kind of uh it's almost like a recipe like anything that implements an interface has to have the things that you've defined on it and that'll make more sense in a second so let's just make this nice and big so this is our public interface i interactable and i'm going to make a public string and we'll say interaction prompt and we can just have a getter on that we can make a um public void interact a function or method and this is going to take in an interactor which we will call the interactor and it can pass back out a ball of whether the interact was uh successful maybe actually instead of doing that we can just return a ball instead of void and we'll get rid of this out parameters we'll just take in the interactor we've got our interface here so now i'm going to go back and make a new script so for example say this cube is a chest and then we have a um [Music] another cube or another object and this one is a door so we've got a chest and a um door and these are both interactable objects so let's create a script called um [Music] chest and we'll create a script old door and we'll pop the door on the door oh and it crashed oh it's good when it crashes isn't it okay so i'm going to save my project now just in case so we're back at this stage so let me open up our um script here so we've got our interactable script i made this door script uh i need to rename this to door something went wrong and it kind of defaulted to its original name but that's fine um so let's start with our chest actually first uh so we'll create a new uh we'll get rid of starting update and after mono behavior we're just going to implement i interactable and you see we've got this red red squiggle now and that's just saying that we need to implement the missing members which are the things that we define so we said that we wanted the interaction prompt and a interact function so we can hit uh okay and now you'll see that these things here that we've said that our interface needs to implement they're now implemented here and we've got our interaction prompt which has just got this um better what i'm actually going to do is i'm going to do a serialized field private string and we can call this um prompt and when we get the interaction prompt we're just going to return prompt and we can actually just use the expression body definition and so we can do that and it will just return the prompt and then in our interact script this is where you would do something relative to the chest so um in the inventory tutorial system that i've got the chest opens it brings up the display for us to put things in our chest but for now let's just debug dot log and we'll say opening chest and because it's a bull we can return through because we've successfully interacted here you may have something that needs to um have some parameters to be met before interact can be successful so from our interactor you could get the player's inventory and then from the player's inventory you could check whether they had a key and if they had the key then you know the door would open and like i'll actually i wasn't going to but i'll actually show you that as a different example on the door because that kind of makes sense so we've got our interact script here and i'm going to make uh go over to our door script get rid of these and i'm going to do the exact same thing so we need to do i interactable implement these members and i can let's go to our chest i'm just gonna i'll just copy these actually so let's just copy that open and we'll say opening door um so for now we'll keep this like this and then i'll implement how we can actually do something and check the player for an object or whatever whatever we may want but first let's make sure this is actually working um and to do that we need to implement on our interactor in our update function we can say here so if numfound is greater than zero so if we've actually found some objects i'm gonna say var um interactable we'll set this equal to whatever is in the first position on the collider array so index 0 and we're going to say colliders 0 dot get component and in get component you can actually get interfaces it doesn't have to just be mono behavior components so we can get so what this will do is it will find any mono behavior that is implementing the i interactable interface so now we can say if interactable which is this variable here if interactable is not equal to null and keyboard dot get got current dot um e key dot was pressed this frame and this is because we're using the new input system so this is the way to do um like input.getkeydown to get that working you need to make sure you're you've got using unityengine.input system up at the top so if we've if we've got an interactable object in front of us and we've pressed the e key then we can say um interactable dot interaction uh or interact and we need to pass in um our cell because we are the interactor that is interacting with this interactable hopefully that wasn't too confusing so let's go back to our um project and let's just see if that's working so we can hit play you can see that we're not overlapping anything at the minute this is on zero you can see that you know i'm pressing e nothing's happening these actually set to the interactable mask they're not because of when it crashed so let's set them over to interactable we'll press play again so you can see that number found zero i go over here number found one zero one this is our chest so if i press e uh nothing happened because i didn't put the scripts on it so that's our door hey when there's a crash in it just really throws you off uh what you're doing so let's press play so we'll go over here and you can see here we can press e and it says opening chest and we can go over here and press e it says opening door so that's the basics of our interaction system working if you if that's all you wanted you wanted to be able to just press a button and do something on a object that's it but let's just take this a little bit further and let's actually check the player um to see whether they've got a key so um let's go back here let's create c sharp script inventory and this is going to be a proper inventory system uh again if you do want to learn how to make a fully fledged a full-fledged inventory with saving a load in stacking splitting stacks dropping items on the ground click the card up at the top and that'll take you to that um but for now this is just gonna be like a very basic script it's just gonna have a bool um on it which says whether we have a key or not so we've got our inventory script here on our um layer object so let's go back to our docs and open up inventory.cs and all i'm going to do here is i'm just going to have a public bull and we'll call this has key and i'll set this equal to false and then in the update function all i'm going to do is uh if keyboard dot current dot space i don't know space keys being used um q key dot was pressed this frame and i'm just going to set as key equal to the opposite so it'll just toggle the has key boolean and here's that zoomed in if you do need to see that a bit bigger and so on our door script not our chest script we've got this um no opening door we can say here um bar inventory is equal to interactor dot get component inventory so the interactor is sat on our player and we know that the inventory script is also on our player and you could do this another way as well on the interactor you could have a reference to you could have like a serialized field inventory reference that was public or had a public property and then we could reach through and get it that way and i'm just going to check the um interactive for an inventory component i'm going to say if inventory um equals null then we can just return false because return so we can't find an inventory then we can't check for whether there's a key so then we won't it won't be successful with the interaction so if we get past this stage we can then say if inventory dot as key then we can debug dot log opening door and if it doesn't have the key and we'll just debug.log no key found and we'll just return false so let's see that working so let's go back over here we've got our player here as key is set to false let's just check that the toggle is working so if i press q you can see that has key is um toggling if i go over to our chest now so nothing has happened we've got opening chest if i go open over to the door uh no key found but if i give myself the key so you can see that has keyboard is now true see opening door because we have the key and no key found opening doors we have a key and now let's take it to sort of level three a new step further by having some sort of ui that it changes based on a prompt that we can define so if i go over to our cube you can see that we've got this prompt um thing here so we can just say prompt is equal to um open chest this can be um [Music] open door if the door was open we could return closed door and so you could you know implement that in your own script but we're just going to have um prompt is equal to open door um say this wasn't a door and it was an object that we could pick up we could just say uh pick up item and we could do that uh well i'll just say open door um and on the cube let's do store items just so it is something slightly so it sounds slightly different and now over on our player i'm going to right click create a ui and i'm going to make an image which is going to drop a canvas on our player so for the canvas i'm going to change this to world space the width i'm going to do 800 for the height i'm going to do 200 and then for the scale let's do 0 0 1. world space and we need a camera so let's drag in our camera into the canvas we've got our image here and we need to reset the position of the canvas so that's down there that's actually really small let's bring that um up here let's go our image and let's make it fill the canvas so we've got this here this is going to be our um interaction prompt i can make this just a little bit bigger it sticks outside the canvas but that doesn't really matter um for the sprite uh for the sprite i'm gonna use this uh ui pack rpg expansion because i really like these um things here for a panel you can just hit download this is all free so with this here i'm just going to drag um i'll drag this brown panel in so let's drag that into our project we'll come over here and we'll set this to sprite 2d ui and we need to swap this to um single hit apply and then we can't actually edit it so we need to go over to package manager go over to the unity registry and this will just refresh the packages and we need to just enable the 2d sprite package so once that's enabled let's go back over to our panel here and we can now pick we can now open up the sprite editor we can now define the um proportions here to make this adapt to the ui a lot better so we can drag that these lines like this it'll keep these corners intact but it'll stretch out these other middle bits um you can see these are all kind of pixel perfect so it doesn't matter if they get stretched out they will look fine so we'll hit apply close this go back over to our image and we can just drag our sprite into there and we can then we can change the pixel per unit multiplier to make the kind of border show up a bit nicer and you could also change the pixels per unit here so we could um you know we can do 64 instead of 100 that'll make it make them a bit chunkier and then we can maybe put this back to um to one just have it to like there so you can see these corner bits they're not all stretched and awful so now if you see that when we press play this is following the player but it's just sticking above their head it'd be good if it would sort of like billboard towards the camera and look at the camera so let's do that in our project let's make a new script we'll call this interaction prompt ui we'll drag this onto our canvas so that's sat there and then let's open this up in our ide so we've got our interaction prompt ui here and here let's get a reference to our camera so private camera call this main cam in our start function we can just cache the main cam so main cam equals camera dot main now you still kind of need to do this this is still faster to do it even though um unity cached the main camera themselves they're caching it on the c plus plus side so there is still a bit of a jump there so it is still quicker to cache it in a private camera variable and then we can just say void uh update actually this needs to be late update so avoid late update and then we can say variable rotation is equal to the main cam dot transform transform dot rotation and then we can set the billboard's transform to look at abba position plus the rotation times by vector three dot forward and then for the world up we're gonna take the rotation and times this by vector three dot up um i'll drop that onto a new line so that should work let's go back to our project you can see now now wherever we're turning the ui is kind of pointing directly at the camera so we've got a nice um a bit of a billboard there so now let's make it actually display something so i'm gonna go um to our image and let's parent some text so i'm gonna parent uh text text mesh pro we'll import the tmp essentials and let's drag that up like that and i'm gonna make this auto size i will center it on all axes and i'm going to make the max text size just a little bit bigger um well we'll do we'll just have the default font but you can change the font there obviously and i'll default this to open um door just so we can see what that prompt is going to do and then let's just give it a little bit of um a shadow so we'll just give it a little bit of a drop shadow just to make it look uh just a little bit pop just to like a little bit more but there you can see we say open door let's go back to our interaction prompt ui script and here let's make a private tm pro u uh gui so text mesh pro u gui and we need to be using tm pro and we'll just say um prompt text and as well as the prompt text let's get the actual panel as well so private um game object and we'll say um ui panel and we need to serialize both these fields so we can access them in the inspector so let's just turn our panel off because you know we probably won't be automatically interacting with something when we spawn into the world and then here we can have um a public void a set up method and we'll call this uh this will take in a string which is going to be our prompt text so we've got set up here um and i'm going to make a public ball so public bull um is displayed and we'll set this equal to false so i'm going to set the interaction uh the prompt text dot text equal to our prompt text we'll set the panel active so set active true and then we can say is displayed equals true and then we want a public void close which will close the panel and say is displayed it's equal to false ui panel dot set active false now back on our interactor script we actually need here a private um interac private i interactable we can say interactable and instead of getting it here in this um you know temporary variable we'll set interactable equal to this private uh variable that we've defined here okay so next we need to get a reference to our um interaction ui so private interaction prompt ui we'll call this interaction prompt ui so what i'm actually going to do is we're going to say if the interactable isn't null first we want to see whether the um if interaction prompt ui is displayed so if this isn't displayed then let's um set it up so we can say interaction prompt ui.setup and we can pass in interactable dot interaction prompt and then we can say if keyboard dot current dot um e key was pressed this frame then let's get the interactable and interact with it and pass in ourselves and then here if we haven't found anything so else um interactable can be set to null and we'll we'll do that if interactable is not equal to null then let's uh null it out and then we can also say um if interaction prompt ui dot is displayed then close the interaction prompt ui by calling the close method but that should famous last words be working so let's go back over to our canvas i'm going to drag in this panel um this is the image here which is going to be the base thing because as we uncheck and check that that will hide the image then on our canvas we can bring in our prompt text on our interactor here we've got this interaction prompt ui we just need to bring in the canvas which has that script on it and that should all be working so if we hit play you can see that the um ui has disappeared if we go over here you can see store items comes up because we're in front of the chest and this is open door store items open door and now you could have this fade in and out you could have it animate in and using something like do tween maybe um but yeah that's kind of how you would set up having an interaction prompt that's billboarded to the camera and responds to the different prompts that the kind of objects in the world have so i hope this video was useful if i said the project files for this video are over on my patreon which is patreon.com forward slash damn poss i'd just like to take a minute to thank my supporters in the 10 000 xp tier we have omega mike and on screen now are all the amazing 4 000 xp tier patrons you want to discuss this video or any of my other videos uh with me feel free to do so in the comments below or join the discord server which is linked in the description below as well but in the meantime thanks for watching and i will see you in the next one bye
Info
Channel: Dan Pos
Views: 80,877
Rating: undefined out of 5
Keywords: unity tutorial, game dev, indie dev, game design, unity 3d, made with unity
Id: THmW4YolDok
Channel Id: undefined
Length: 33min 50sec (2030 seconds)
Published: Sun Apr 03 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.