Unreal Engine 4 C++ Tutorial - Using Interfaces - UE4 / Unreal Engine 4 Intro to C++

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
everyone welcome back to another unreal c plus plus tutorial again we'll be taking a look at a single topic and this one will be covering interfaces if you're here you're probably aware of what interfaces are and where you may want to use them brief overview though is they provide a very simple way to have some agnostic kind of class communication between multiple classes that may not quite fit inheritance but will have some similar functionality such as things which can all be interacted with may not necessarily be an interactable class you can therefore create an interact interface which is what we'll be creating today and then inside of any class which implements the interface they can have their own very unique functionality but anything can call those classes and just assume or check that they have that interface available so to begin we're going to go into our c plus classes as i've done in the past i will be utilizing some of the existing functionality within the project this i'll once again be using the character base class just because i already have that implemented in the world i'm also going to go back to one of the components of using the line trace component so you may want to check that video but this is just a way to very quickly because it's doing a trace into the world i'm going to use that to call the function on the interface the main thing about the actual interfaces themselves though that can all be followed along from scratch so to get started we'll just create a new class as always the interfaces in here can be found at the bottom so under the unreal interface i'll place this into its own separate folder called interfaces and i'll call this one the interact interface with that done we can just hit create class and let the engine do its thing when that's finished compiling we will have a class very much like any other in the header and the code file the main difference with interfaces is that they do not have their own c plus or code file implementation the way that we'll be using these is we add as the comment already says here we'll be adding our function declaration in the interface and then the classes which will implement the interfaces will actually have the definitions of these functions the other thing i wanted to cover is that there's a very standard way that you'll see these implemented so i'll show that way and there's a way that we can use this without having any blueprint the first one i'll be showing is a very standard way that you'll see interfaces implemented so i'm going to do this with a void function named interact you'll then usually see this implemented with a u function and then inside of the u function you'll usually see that the blueprint native event specifier is used i'll also give this a category but of course the blueprint native event specifier here is indicating that we'll also be using this in blueprint and it means that when we put this into our class that we'll be using the interface functions we'll be using the implementation function rather than just the kind of native pure function so i'm also going to show the other way that we can do this i'm going to create another function of type void named interact pure so this is just in case you wanted to do the same sort of thing but without the requirement for blueprints functionality and having that implementation version we still need this to use the u function specifier though some means that we need to specify our function as being virtual so that the class that we'll be implementing our interface on will know that it's going to override this function named interact pure the other thing that we can do because we know that we won't have any class definitions here so we're not going to place anything inside of the interface code file we can set this to be equal to zero which means when we're compiling this it will know not to look for the interact pure definition in the code file of the interface again this will be in the code file of the class using the interface okay so the next step is inside of the class that you want to implement the interface so to have this callable function we need to do something at the top of the class we need to add to the signature here a comma and then the declaration of public and the name of the interface that we've called this so this is going to be i interact interface because interfaces are always prefixed with an eye inside of rider this automatically knows that the include is meant to be put up here if you're using visual studio or something else you may need to use the include here so the next important thing is when you have the interface declared as being included in this class we then need to make sure that we have a definition of every different function which is included within that interface if you don't do that that can cause problems so we're just going to come down here i'm going to put these in the public section and remember we have those two different functions so the first one was our blueprint native event so remember this is a function which won't have its own c plus functionality is going to expect this to be done in blueprint but we will have the option to use the implementation so this will be our void interact underscore implementation and of course we want to specify that we'll be overriding this as well and just a reminder that this is going to give us a blueprint function if we have a class deriving this in blueprint for the character class next we need to make sure that we include the pure version so this will be a virtual void and that was interact-pure and we're going to call the interact-pure override and again just a reminder that this will be our c plus only version so when i want to get both of these and make an implementation in the code file so i'm just using again the rider automation here to generate the implementation this will automatically create the functions inside of the code file and this is where we're going to put the functionality or any of the classes which are calling the function making that message from the interface to the class that they're housed on so i'm going to keep this nice and simple i'm just going to provide these as message logs and the main thing is checking how these are going to be called and when they're going to be implemented in the world at run time so for the interact implementation i'll just place a ue underscore log of type log temp and warning and then the text i'll just print out implementation so that we know which version is being called in a very similar way for the interact pure function it'll be the same types again but the text will just print pure this time now the final step is to get something to call these this like i said i'm going to use an existing class that i have here or a component you could do this as an interact class if you had a door or a chest or something that could be interacted with usually a character pressing e or something that would call the message to the interface on those interactable items so that's the way that you would normally use these so as you can see here i'm now in my line trace world component if you followed the other videos in this playlist this was the one which is just casting a line into the world and the reason i'm using this is this is passing everything back including the actor that it's hitting and i can put this on an object which just spins around so wherever the object is in the world this is going to very easily find the character and call those functions on the interface so where i'm going to do this i already have the line trace being fired into the world on the event tick so this is happening constantly inside of this we're checking if we hit something and if we do what i want to do is i'm going to remove this screen print message here we don't need this anymore and just below this i'm going to find the actor that we've hit check that it has a interact interface on it and then if it does we'll call or access one of those interface functions now again there are a couple of different ways that we can do this so i'll show you both ways just in case you wanted to use one over the other so the first thing that we want to do we're going to get the hit actor we'll find out what the class of that actor is and then we're going to check from this if it implements the interface so these are all pre-built functionalities that we can call we then want to check the interface type by using the static class and we're checking that against the u interact interface which is the one that we've created so if this fails it means that the object that we've just hit or the actor that we've just hit doesn't implement the interface that we're looking for so we can probably bail out of this and not try and call any functions if it does have that interface then we can take the next step which is to call a function that interface is implementing so the first one we can try and call is the pure version we're going to cast to the type of i interact interface we're going to get the hit actor and we're going to call the interact pure on that hit actor so remember we're not calling interact pr directly on the actor itself because we don't know what class that is we're calling it through the interface so the eye interact interface has a function named interact pure that's going to pass a message on to whatever type of actor that we've hit and we didn't need to cast to that actor now the other option because we also have the blueprint version that has a slightly different syntax so this i'll just again comment that that will be calling the c plus plus only implementation the syntax then for the second type is going to be again using the i interact interface with i'm going to use something which is specific to interfaces which is the execute underscore and the name of the function which in this case was interact so remember we in the interface we had one function called interact which had the u property with the blueprint native event and the other function called interact pure which just had an empty u function so this is calling the blueprint version and again what we're using is we're passing this message to the hit.getactor which is whatever actor the line traces hit and again this doesn't need to know the type of class so we can avoid casting there so if we were to compile and run this now and the line trace was to find something both of these would work it would call the version in the blueprint it would call the underscore implementation and it would cause a pure version so it should print pure it should print implementation and if we also had a print string in the blueprint which i'll show at the end of this it will also call that as i mentioned there's also a slightly different syntax that we can use so i'm just going to comment the site first of all and we're going to use the second syntax as another way just to demonstrate the options and i'll go over why in just a moment so one of the main differences that we can see here is that we are creating a new object named interface and this is the result of casting again to the type of interact interface and finding if that exists on the hit.getactor so this way we can reuse this new object that we've just created wherever we want throughout this class as long as we've had a successful return of it here so this is the option i tend to take just because we can saw it once here and we never need to do this line of checking every time that we want to use this again then this way again the the syntax is slightly different so the first way that we did the call was to the c plus only implementation when we have an object of this we simply call the interface and then access the function within that interface so interact and then call function interact pure is the equivalent of this cast here and then calling interact pure now the other nice thing about this is it makes the rest of the syntax very short even if we're doing the execute versions so this time it would just be interface and then the access modifier and then execute underscore interact then once again passing in the hit hit.getactor because remember whenever we want to use this implementation version it needs to know which actor it is calling that on so both of these options will do exactly the same thing you can test that if you wanted you can compile this and run it and test it with one version comment everything out and then test the other version but you'll find the results are exactly the same it's generally just a preferred syntax and like i mentioned for the reason that we then get this object which is very lightweight and much easier to kind of read i tend to prefer when working with interfaces using it this way so when you have your preferred method what you want to do is compile this save everything compile and head back on over to the engine so the way that i'll be using this the line trace world is on a blueprint that i've created in a previous video it's just a simple actor it has the line trace component on it and then it's going to spin in a circle and it's basically just rotating continuously whilst the line trace is tracing into the world you'll see that from this yellow line and if i step into that that's going to be calling the line trace checking if it's hit something with the interactable interface on and if it has that will call the functionality that we've just declared in our code so if we test this now we should expect to see the pure and implementation ue underscore logs being printed in the log output here so just clean this and go back into the world wait for this to come around and hit the character and we can see nothing actually happened there it may just be that that's too high i'm not 100 sure try again okay so yeah that was just a little bit too high there we go so we can see every time this hits multiple times per turn we're getting implementation and pure so those are being called purely through the interface the other thing that we can do now is that the character class that we have so i'm using my bp underscore character here this should now also have the option to use the interact function here so if we right click on this we can use the implement function option and then from this we'll do a print string and again this will be called and if this will just simply say hello whenever the line trace hits us so we've now got this being printed up here saying hello whenever we're hit by the line trace that's the blueprint implementation part of this we're then having the code implementation version of this being printed down here as well through the log outputs so that is all of the versions of those messages being passed from another actor in the world or component in this case to the interface and then passing that on to the owning class so the important thing here to remember is if we go back into the code very quickly that at no point is the line trace component checking whether we're hitting the character class or accessing functions specifically on that class so the idea now is that i could also add this onto my pawn class i could put this onto any of the other classes that i have in my project and as long as they implement the interface the same way that we did in the character class where we create the implementation in the header file and then those functions which are on the interact interface and then put those functions inside of the code file to do something then this line tracing functionality will interact with any of those in exactly the same way without needing to check the classes this avoids doing things like expensive casting to check whether something's a certain type of character or a certain type of object and then trying to access functions directly in those this will just pass a message along it's essentially saying i've called your interact function whatever that is for you and then the classes themselves like we've seen in the character class can implement their own very custom unique versions of that function and just to remember that if you ever wanted to come back and use this as a reference i've shown you the two diff the the well the two main different ways that you can generally find these there are probably other ways but these are the ones you see most often so you can always check whether the other class is implementing the interface and then call it through the hit object or the object that you currently have a reference to or you can store the interface as an object and then once you've successfully if you know you definitely have a valid reference to that interface then you can call the functions through that interface which we passed on to the owning actor likewise something that i haven't seen done in many other tutorials is that like mentioned this is normally the default way that people will show you how to implement an interface function so it's using some generic kind of void undefined function with a blueprint native event on this just because that's i think the way that the documentation originally stated to do it and if you don't use this you will get certain errors and warnings as well if you don't have some kind of specifier in the u function here so you can also see with this implementation a way that we can do it with a kind of pure function where nothing needs to be run through blueprint this is really the important thing here because we want to make sure that this class is aware that it's not looking for any implementation or definition of this sorry in the code file hopefully this helps when you're working with interfaces now they're very powerful system to get used to inside of unreal they allow for some really impressive kind of flexibility between classes they can really help improve on performance by avoiding casts to actor classes and they also open up the flexibility for many different types of classes to implement very similar functionalities even if they're completely different classes that wouldn't normally derive from each other so another way to think about this actually is with the interact functionality here if you think of something like a zelda game where you may have a set of objects which are all interactable they would be maybe child classes of the bass interactive object so that would in its own way need to be interacted with but then you also have things like npcs or other characters which can also interact the main character but of course they're not going to derive from the interact-based class it's not an object to interact with it would be a character class you could put this interface on all of those different types and that interact message can do completely different things depending on the class that it's on and the functionality you put within those definitions so hopefully that makes a little bit more sense why you may want to use something like an interface rather than just sticking purely with inheritance and the kind of derived class functionality so of course if you have found this interesting or useful please do leave like and share the video around that really helps the channel to grow and reach as many people as possible be sure to subscribe to the channel to be kept up to date with videos like this on a weekly basis and of course hit the notification bell so that you get those updates as ever though thanks for watching and i will see you all next time
Info
Channel: Dev Enabled
Views: 5,102
Rating: undefined out of 5
Keywords: devenabled, devenabledUE4C++Intro, gamedev, game dev, game design, tutorial, tutorials, unreal engine tutorials, ue4 tutorials, unreal engine 4, ue4, pluralsight, course, learn, education, ue4 content, audio vis, audio viz, unreal audio, ue4 audio, game Mechanics, ue4 C++, unreal C++, unreal Engine c++, ue4 C++ tutorial, unreal engine 4 C++ tutorial, interfaces, c++ interface, ue4 interfaces
Id: wNDrCcjtLdA
Channel Id: undefined
Length: 17min 8sec (1028 seconds)
Published: Sun Feb 07 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.