Unreal Engine - Casting and Interfaces Explained

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys and welcome to another one of my videos so in this video we're going to primarily be covering the difference between casting and interfaces but we're also kind of going to be dabbing into inheritance a little bit and and classes to some degree but the main focus here is the difference between casting and interfaces and the reason i'm covering this is because i've had a lot of people ask me like in the discord or on youtube comments like hey is it better to use casting or interfaces and well that's a that's a pretty hard question question to answer well it's impossible to answer that question really because it's sort of like asking is it better to use a hammer or a screwdriver right because they both have different applications like hammer is used for nailing things and a screwdriver is used for screwing things in so i'd really have to ask you then okay well what are you trying to do right so one of them is not necessarily better than the other they just have totally different applications and people seem to think that they're these interchangeable things where you can use casting or you can use interfaces for stuff and that's really not necessarily the case you really want to use casting when you should use casting and use interfaces when you should use interfaces so this is just going to be an explanatory video i have a little scene set up here and i have some stuff already implemented just to give us a real world example that you can actually look at and it's tangible to help you understand when you would use casting versus interfaces so what we're going to do here is i already have it set up so that when you walk into one of these colored blocks it changes the color of your gun and also changes the color of the projectile that it shoots so if i hit this brown box it'll shoot this brown projectile and what i want to do is make it so that if i shoot anything in the scene like one of these chairs or even this little cat here i want it to change the color of the thing that i hit to whatever color the sphere is at that moment so it's sort of like a little paint painting game right so in order to do this um the first thing you might think about as a way to accomplish this is casting right so if you're not familiar with anything that i'm talking about i'll try i'll try my best to explain things for beginners as well as for like intermediate people but most programmers will initially come to the conclusion like okay i should use some sort of inheritance hierarchy for this where i have a parent class for my furniture or my items and then that parent class has the functioning functionality in it um to set the color of them of the object so no matter what i hit um it all just it all just kind of works so we're going to kind of go down that method first and then i'm going to explain why that doesn't work out too well in this case so you can see what i've done here is i have my four different furniture items i have my table my lamp my couch and my side chairs here and you can see each one of those is down here as its own blueprint and then each one of these blueprints derives from bp furniture base right so if you don't know what derived means i'll try to kind of explain this very very quickly because it's not really the point of this tutorial but in unreal or in a lot of programming language there's this thing or there's a concept of inheritance and it basically means that different classes or different blueprints can inherit from other classes or blueprints so a good conceptual way to think of this like is an example so if you think of any type of hierarchy so maybe we can think of food right so at the top of the hierarchy you just have food right and then maybe below food in the hierarchy you could break food down into fruits vegetables and meats right so then you have three subcategories and then you could break each one of those down even further so fruits you could break down into grapes and banana and then vegetables you can break down like carrot and spinach and meat you can break down a chicken and pork right so you can keep breaking things down more and more and more but the important thing is that as you break things down they are still the thing above it right so in the case of like grapes like grapes are still a fruit and fruit is still a food so as you move up the chain it still logically makes sense and that's the way inheritance works as well so you can see here this is a really simple example furniture is at the top of the hierarchy and then below furniture i have four different categories so i have a chair a sofa a table and a lamp right but you could break one of these down even further if you wanted to um have more control so like for example you could have a table and then you could break a table down into like a foot table and a coffee table right so at a high level that's sort of what inheritance is and the cool thing about inheritance is that you can treat the child classes as any of the parent classes above it so if you have a reference to a grape in my other example well you could you could easily cast the grape to a fruit because we know it's a fruit you could also cast it to a food because we know it's a food and it kind of allows you to share functionality so any anything inside of a child class will have access to the parent classes functions and variables so in the case of like the the food if the food class at the very top had an eat function right well if you had a reference to a grape or a piece of chicken or the spinach right if you had a reference to any of those bottom level classes for foods you could still call that eat function because it inherits all the stuff from the classes above it so that's sort of a very quick rundown of what inheritance is and hopefully that kind of makes sense so what i want to show you is that since each of these blueprints inherit from the same base class we can make use of that to simplify our code significantly so in our first person projectile which is just this little sphere that gets shot out inside of my event graph i already have some code here so what we're doing is we're looking at the hit event so this event gets called whenever the projectile hits something and what we want to ultimately do is we want to call the set material color function which is you can see if you look at the target the target is my bp furniture base i want to call this function off of whichever object we hit assuming the object we hit is a piece of furniture and then we just want to destroy the projectile so the hit event gives us the other actor that we hit and this is where this is where casting and inheritance comes in really nicely because all we need to say here is cast to uh vp furniture base and so what we're saying is take this object that we hit and try casting it to a furniture base and so the cool thing about inheritance is that this cast is going to succeed whether or not this is a lamp or a table or a chair or any other type of furniture that derives from this furniture class that we've created this base furniture glass and so by doing this it allows us to very easily add more furniture without having to continuously add code to set the color of furniture because the furniture color setting code is inside of this base class and then we can just hook this guy up like so and then one thing i just want to point out real quick is you notice it has this cast failed and a cast will fail in a lot of cases and the reason it fails is because you're trying to cast to something which is not part of that hierarchy so going back to the food example if we were to be shooting our gun and there was a bunch of food in the scene right and we hit a tractor if we tried to cast a tractor to a food it obviously would fail because a tractor would never inherit or would never be a child of food because tractors are not food right so in some cases cast will fail and that's perfectly fine it's not going to give you an error but it is going to run this pin right here and so if you wanted to handle that case you could do it right here but in our case we don't really care right because if the ball hits a wall or something that's not a furniture we just want it to fail and not do anything so now if we run this and we shoot a wall you can see it's it's failing but if we shoot one of these pieces of furniture it actually sets the color of the furniture to whichever thing we hit whichever color we currently have selected so that's a really good example of how to set this up but the problem is this freaking cat right because the issue is that this cat is a pawn and all the other furniture is an actor and we can't really we can't really make this cat a child of the furniture class because a cat is not furniture right i mean technically we could do it but it's going to mess up a lot of things and it's going to be kind of confusing right because if we look at the hierarchies here if we look at the hierarchies here if you just hover over furniture you can see about five down from the top or yeah if i down from the top it says the parent at or the parent class is actor so that means we're deriving from actor but if we go and look at our little cat blueprint here you can see his parent class is a pawn so if we were to change our cat to inherit from the furniture then his ultimate parent would be an actor and he would no longer be a pawn anymore and we need him to be a pawn because we need him to walk around we need him to animate and be able to pathfind and all that good stuff so we can't really do that so now we're at a now we're at a crossroads here of okay well what do we do because we can't we can't just make this guy inherit from furniture because he's not furniture so this is a perfect example of when interfaces are meant to be used so hopefully hopefully that can make sense as a like oh we ran into a problem what is the solution the solution is interfaces and the reason it's interfaces is because we want to reuse functionality between classes that essentially have nothing in common so let me say that again so we want to use an interface here because we want to reuse functionality between classes that have like nothing in common and do not inherit from the same thing right so let's go ahead and i'm going to be writing this like from scratch as we go so i can show you how you would convert this over from using casting to interfaces so the first thing we need to do is we'll just come out here and maybe we'll just do right here so we're going to right click and create a new interface i think it's under blueprint interfaces and then you can name it whatever you want so i'm going to call it dpi for blueprints blueprint interface and then i don't know what we should call this like paintable so the idea is that anything that we want to be paintable is going to inherit from this interface very sorry going to implement this interface so you can already see the advantages of this because now no matter what we have in our game it doesn't matter if it is in the same hierarchy or not it can just implement this interface i'll show you how to do that shortly and be able to implement the functions inside of this interface and be able to be paintable so if we open this guy up you can see it looks a lot like a normal blueprint except it doesn't have all this stuff over here on the left where you can add variables and event graphs and macros and components right like there's no viewport for it all it is is a list of functions that you can create so if we come over here it gives you one by default so let's actually rename this to paint so this is going to be the paint function and then it needs to take in the color so let's add an input parameter over here and then just call it or sorry we need to make it a linear color and then we'll just call it color i can type and then compile and save so you can add as many functions over here as you want to an interface so you can add another one and as many as you want right but for our case for for this particular interface we really only need one function we just need a function that allows us to paint whichever object implements this interface so now going back to our cat and our furniture we need to make it so that each one of these implements this interface so that way they can share this paint functionality without having to somehow both inherit from the same thing so let's go back to our furniture first and fix our furniture to use this interface so the first thing we want to do is come up here to our class settings and this is how you implement an interface so if you go to class settings you can see there's a section on the right for interfaces and we can hit this add button and search for our paint interface so here we have bpi paintable and then when we do that it adds it here to this list and then more importantly over here on the left under interfaces it adds the function so if we take this function and we right click on it we can then actually implement it and when we do that you can see it creates a new event for us called paint and here is our color variable and so what we want to do is we want to do whatever the furniture was doing before to set the color but now we want to do it inside this paint paint function so if you look at our class it's really simple so i just made this function called set material color and so all we're going to do is just call this guy from our interface and hook it up like so so now whenever the paint event gets called via our interface we're going to set the material color which is going to change the color of the furniture so now it's hooked up to use our interface so now we just need to do the same thing for the cat and then we need to update the projectile to call this interface so let's go look at the cat um [Music] cat here he is open this guy up so i believe for this guy i haven't really done anything yet because i kind of wanted to show you guys how i'm doing all this coloring stuff in case you're curious so what i'm doing is i'm taking i'm taking the thing i want to change the color of which in this case is the skeletal mesh and then in the construction script drag this guy in and i'm saying create dynamic material instance and then all you got to do here is select the material that you want to create the dynamic material instance for and the reason you need to create a dynamic material instance is if you don't already know let me show you the material real quick and then it will make more sense so if we click on our little cat skeletal mesh and we go to his material we open this guy up so you can see the way this material is set up is it has most importantly this color variable up here at the top and it is going into the base color so whatever value is set for color is going to be the ultimately the color of our cat and you can change this variable before you start the game but if you want to change it during runtime or while the game's running you need a dynamic material instance so that's the reason we're creating one of these dynamic material instances and in the source material you just select you know like the the material so we have m low poly cats we're going to select this one and then oh it looks like i already made a variable for it but what you could do i'll just delete it so what you can do is just right click on the output pen and promote it to a variable and call this our material instance so now we have a material instance which allows going to allow us to change the color of the cat at runtime so now we also want to implement this function or this interface and make use of this material instance so if we click on class settings just like we did for furniture we want to add our bpi paintable and then again right click say implement and then sort like we did before we want to change the color of the cat so before i already had a function which would do that for us but i don't have one um so we're going to write it real quick ourselves so i'm going to drag in the material instance and then i'm going to call set let's see set vector parameter value so what this does is it sets a parameter inside of our material and the material is over here and the parameter that we want to set is called color so we want to make sure that we pass in a parameter name of color and then for the value here it is the value that we want to pass in so we're just going to pass in the color and then i think that's all we need to really do so now we have our cat and our furniture base class both implementing the paintable interface and both implementing the paint function and both changing the color of their respected mesh so the last thing we need to do is go back to our projectile and instead of casting the thing that we hit to a furniture we need to check if the thing that we hit implements this paintable interface right because now we're going to be painting more than just furniture we're going to be painting furniture and cats so we can't simply cast well actually let me point out one thing we could still do this using casting if we did something like this and this is a bad idea you don't want to do this but i just want to point it out because i've seen i've seen some people do it and it is technically possible so what you could do is you could say okay my cast to a furniture failed let me try casting to a cat and you can hook that up to the failed and then if that succeeds then you can come up here and well i guess you would need to call your own function inside the cat so you could call a function inside of your cats which you don't really have one but you could call a function inside of your cat to set the material color and then destroy the ball as well so you could do something where like if you have cats that are paintable you have furniture that's paintable and maybe you have like i don't know uh scenery that's paintable like trees and stuff you could just keep casting and casting casting and casting until one of them succeeds and then you can set the color of that one but obviously that doesn't scale very well right because then you're just gonna have a bunch of casts in the castle gas and actually kind of gets expensive because you're just continuously checking and checking and checking what i hit what did i hit so you don't really want to do it that way so like i was saying the real the real correct way we want to do this here is let me get rid of this stuff we'll keep this little destroy over here so what we want to know is does the thing we hit implement the paintable interface so we can take this actor and there's a handy little function for this called uh does implement interface and so this is going to return true if it implements whichever interface we specify here so obviously we want to search for the paintable interface and then we'll drag off of this guy and do a branch and this is again checking if it implements the paintable interface and if it does then we know we can safely call this paint function that we've written because remember this has a paint function we can safely call that function so let's just move this over add a little reroute node here so if we drag off of this we can call that paint function so you can see it's under bpi paintable so this is what we want right here and we're going to hook this up to the true and then finally destroy the actor after that and so for the color it's just going to be again the color of the projectile so we'll drag that in and there we go so now just to recap here what this is doing is when the projectile hits something it's checking if the thing that we hit implements this paintable interface so the cool thing is that like i said anything that implements this paintable interface the projectile will now be able to paint and we don't have to ever change the code inside of the first person projectile ever again and it's better than casting because it doesn't matter if things that the ball is hitting are inherited from each other as long as they implement this interface we're good so if it implements that interface then it calls the paint function and it destroys the actors now if we run this hopefully this works let's try shooting the cat okay so there we go then we change to white and to blue and hopefully yep we can still shoot our furniture and things work out nicely um yeah so i think that pretty much concludes the video hopefully that makes sense to you guys of when you should use one versus the other if you guys like the video please leave a like and subscribe i also have in the link or in the description of this video there's a link to my discord if you guys want to join there's also ways to support me like via patreon or crypto or donations of some sort so if you guys want to do that that's always also very appreciated otherwise i will see you guys in the next video and thanks for watching
Info
Channel: Reids Channel
Views: 27,106
Rating: undefined out of 5
Keywords: Unreal Engine, Unreal Engine 4, Unreal, Unreal Engine 5, UE4, UE5, Tutorial, How To, Blueprints, Reids Channel, Reid's Channel, Casting, Inheritence, Interfaces, Interface, Child, Parent, Derived, Cast, Implement, Explained, What
Id: qLpjGxyfZLg
Channel Id: undefined
Length: 21min 30sec (1290 seconds)
Published: Thu Sep 09 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.