I feel like these videos on how engine functionality actually works are an incredibly valuable thing. There's so much cryptic half-information and guesswork out there that getting a coherent understanding by yourself is a pretty laborious task.
You are 100% correct as it is quite laborous but the returned value is exponential compared to the applied effort. Understanding if things are possible or better put, scalable or if there might be more unknowns preventing success (such as needing double floating point back on UE4) are worth their weight in gold. It's one thing to waste a bit of time as shown in the video by doing extra interface stuff, but another matter entirely to have to rebuild a feature all over again after determining a roadblock with the engine in one way or another due to incorrect expectations of how something works. It's an invaluable skill that often comes with more and more experience and bigger projects & the concept applies to any software really
@@arnaudkaho7137 because someone watching tutorial content mainly targeted at hobbyists/beginners will most definitely know how to look into engine code and be able to understand it.
A good analogy could be like when you tell children to stay away from fire. Fire can be very dangerous when handled improperly, and children are just too inexperienced to explain, and be expected to retain, when it's safe and when it's not safe to use it. So to avoid any chance of it becoming a hazard, you warn them to stay away from it completely. Which is why I get why people say to avoid casting. But like fire definitely has its uses, there are many many uses for casting, and eventually you'll mature enough to understand how to be responsible with it.
There are reasons it exists; reasons Epic actually put it in the Engine. Every project ever, has casting to some degree. The problems are way less pronounced today. By 2025 ish, its predicted the majority of PC consumers will have at least 32 gigs of ram. Consoles already have 32+ gigs of ram. Its extremely hard for an indie to work at a scale where the pitfalls of casting will actually apply. When you work on large projects that have asset linkers, Data Assets like DA_CharacterAudio or a game like Fortnite, literally thousands of potential skeletal mesh skins. You need ways to load assets in and out without referencing the entire asset tree. Incorrect Casting there will literally prevent most players from being able to play due to lack of memory or ungodly load times with linking like 10 gigs of audio directly to a player character needlessly. But you are right. For most people? Most devs? Most projects? What they are Casting to will already exist in their game anyway. Its already loaded and therefore has virtually zero cost. Casting can also prevent hitching common in a lot of titles by just hard linking related gameplay assets.
oh for sure! dont just randomly cast to a bunch of stuff without knowing that it also loads in a bunch of assets. and even though i'm advacating for using a cast every now and then, i still think setting up an interface call makes more since 9/10. people are just unreasonably affraid of casting and don't actually make any consideration for it as a result.as you say, for most people, they're working on a scale where even if they do mess things up, it doesn't actually hurt all that much with modern computers having more and more memory .
I wanted to throw my hat into the ring as well, but decided not to. Casting is indeed fine, issue arises when you cast to things not loaded in memory. So if that is an issue, you can circumvent this by casting to base classes instead, which you can setup with the basic skeleton functionality you want, drastically reducing the potential spike in memory used. I used to do interfaces all the time for literally everything, then I realized I was adding unnecessary overhead to the program. Interfaces are good for when you want to share functionality in different classes. It took me a while to realize this, and I only figured this out when I started using the C++ side. A tool is only as good as how it is used. Sometimes casting is better, sometimes interfaces are better. Interfaces can add unnecessary complexity to your code if used incorrectly, which I have done a lot. This is ignoring that under the hood, calling an interface function results in a cast anyway. So if casting is bad, then so are interfaces. As a general rule, if it's only ever going to be one class, use inheritance to your advantage and cast, if you are going to use different unrelated classes (for whatever reason) use interfaces. That said I still like using interfaces, if I think there might be future use for it. The cost is generally low either way if used correctly.
i think this is pretty much spot on. casting is fine, but shouldn't be a crutch in situations where it noticeable harms performance. it's 1 tool in a wide toolbelt that has it's own usefulness within it's own context. in general overdoing interfaces will do less harm than overdoing casting so i get that a lot of people want to be on the safe side and avoid casts altogether. I personally think "X is bad" should be a mindset that we avoid, "X is bad at Y and shouldn't be used for Z because of that" is good though. :)
Came here to post the same thing. To put a fine point on it: avoid casting against blueprints, which will always load every part of the blueprint into memory if it isn't already, which is why casting against base classes is the right way to go. (Source: I was casting against an NPC BP once and absolutely wrecked perf on debug builds of the editor.)
So refreshing to get real explanations. Your videos have helped me understand so many things in the engine from “why” instead of just “how.” More of these please!
I thought the dependency of casting is not recommended when it's used to access a class of a general actor/object reference, instead an interface can be used, because it's easier to maintain. An example is the magnet ability in Zelda BOTW, when it's activated all metallic objects glow and are selectable. Traditionally, all those objects would be children of the same Metallic Object class, so, when they are selected you need to cast to the parent class. Then let's say Nintendo bought an asset from the marketplace which contains ready to use metallic weapons, but they are not children of the metallic object base class, then, they need to re-write the objects instead of just implementing an interface on them
yes, for a lot (by far most) cases setting up your code to use interfaces will both preform well and be easier to scale up in scope. Certainly don't throw casts all over the place but if you understand what the actual downsides of a cast are, you can also decide when they are worth using. For the example you give here, the player class doesn't need (and shouldnt) to know about every single possible object to interact with so it just uses an interface and lets the object itself figure things out. That way, specific objects can also easily implement their own unique code when interacted with. Now instead, let's say we have a weapon and that weapon needs to know some of the player's stats in order to do something (assumeing damage calculation is done on the weapon). there is no real harm in casting from the weapon to the player here, since the weapon is never going to exist without the player and the weapon simply needs to access a variable that exist on the player. Now, that does mean that this weapon now can only be used by the player but if you design your code with a bit of forsight, you probably would have a parent class "Combatcharacter" or something like that, which has all the combat related values on it, and you can cast to that instead, now it will also work on any other class that inherits from "CombatCharacter" and there's no real downside to it anymore. about 95/100 times interfaces will end up being smoother to work with and better for memory, but those 5/100 times that they're not, it's dine to use a cast if you know when to :)
This gentleman is absolutely right! A wonderful easy explanation about why casting is a real feature and it has a reason to exist. It has its benefits and weak points. So, yes use casting if you know that object is already loaded ... Game instance for example, always loaded
I think the reason why people say not to use casting is because it's easy to get out of hand really quickly with dozens of cast nodes, and for the most part, there isn't a need to cast. If you're trying to check to see if the overlapping actor is the player for example, you can use tags which doesn't create a dependency. If you're trying to call a function, you can use an interface, and if you're trying to communicate between actors, you can use dispatchers. The original Epic tutorials told everyone to use Event Tick and Casting because they saw blueprint as something you only use for prototyping, and a lot of the official tutorials were written by artists and not programmers. It's not a rule of Never use casting. It's more, avoid it if you don't need to use it because it's just lazy programming and unnecessarily eats up memory. In your own example of casting to the Reaper class when you're using that ability, imagine the scenario where the Reaper is spawning a dozen projectiles, so you're just casting from the projectiles to the Reaper, because as you said, the Reaper is the parent. But now imagine that the Reaper shoots the 12 projectiles and then immediately dies to the player's attack. Those 12 projectiles are all storing the Reaper in memory even though he's likely been destroyed. So not only is it a waste of memory, but also you're going to get errors when you stop playing due to the projectiles trying to reference something that doesn't exist anymore. This causes instability and creates a greater chance of your game crashing for unknown reasons. It's just a bad habit to get into.
i totally get this, but the advice of " avoid casting and event tick" is taken as a hard and fast rule by a lot of people who don't actually understand the "why" behind that advice , i see it pop up in a lot of places online and i figure that having a little bit more content and info out there going into the nuanced rather than just "spam casting, because it's easy" and "casting is literally the devil's work" will be good for people to learn how things work and when certain choices do and do not have a relevant impact. as far as the reaper example goes, those projectiles will also be gone in a handful of seconds so even if the reaper class stays in memory for that little time longer, that's really not an issue.
literally just went through a huge decoupling process and at the end of it all i realised i could have just casted in so many places as many things were already loaded a lot of the time e.g player controller, player character, game mode etc
oof that is painful XD but hey, it's better to know HOW to decouple things than not know how to do it at least, so that's an upside :) but yeah sometimes a quick and dirty cast will save you your sanity and not actually cost anything XD
Yes sadly because of misinformation its easy to not realize that EVERYTHING in your level is in memory already... The ONLY things u dont want hard refrenced is things that are not always in the level or in every level. If you have a 1 player character game with 1 Level you can litterally hard ref everything otherwise you need to use soft refs and plan accordingly
Solid video, and I agree. Some casts have to happen, like I open loading a level by casting to game_instance which I use as a reference container. There is literally no way to get the GI other than a cast. However, I do try and leap frog references as much as possible to minimize casting but a few casts to get gi, game mode, player char is totally fine.
yeah GI is another one that's pretty much a free cast. everything in your game already exists in your game instance, so unless youre casting to a GI class that you're not using which... why would you? youre pretty much free to cast to your GI anytime you want ( i mean, within reason of course xd)
The correct answer is to avoid casting if you can, but use it if you would otherwise need to jump through hoops to not use it. And don't feel bad about it.
both sides of the arguments are important to hear, you need to learn about why casting is bad, but also that you can use it when it makes sense. too many people learn about the downsides of casting and go into a "NEVER EVER CAST EVEN IF MY LUIFE DEPENDS ON IT" mindset, which is way too far in the other direction XD
@@thegamedevcave I think the titles of the videos are getting in the way of the message. Both videos are basically about the same thing: when to use casting and when not to. The content of both videos are great, but I think the titles could be a little more descriptive.
I hope beginners find your videos before others because man, the guys that rank when searching back when I watched tutorials, looking back now, are the worst.
LOL. This is correct. I like to say it makes a difference whether you are casting to a sardine or whale. I think one video in particular freaked everyone out because the argument on why it was bad was compelling, but then it should have been clarified that there are times when it is, as you say, perfectly fine.
So to clarify, to save time or if there's no other option then use casting if both 'objects' are loaded into the level anyway. Such as actors in the level, game mode, level blueprint etc.. And that 'get actor of class' is the same cost as casting. I've been using interfaces in pretty much every situation I can but I came across a time I absolutely needed to cast to then use my interface to carry across variable data. Odd situation but it worked lol
Pretty much, get actor of class has the same memory implications as a cast (so does simply having a reference variable of that type) but get actor of class also is rather expensive to execute on top of that.
@@MonsterJuiced yeah by a pretty significant amount, what it does ( more or less) is try all actors 1 by 1 to see if they're of that class ( so, casting pretty much) and once it has found one it returns a reference to that. it still creates the hard reference that is the main issues with casting to begin with, but also takes up computing power to find an actor in the first place. it's not as bad as "get all actors of class" that one is even more expensive but it's still not something you'll want to be doing often or on a large scale.
You can run a check / graph to see how heavy the load for casting is. I can’t remember it off the top of my head, but it will show exact memory usage of all the references you are calling with the cast. If you get a lot of nested ones it can be expensive. I imagine it’s more important later on with regards optimisation, I still think interface is the way to go.
I usually cast a reference once at begin play convert it to a variable then i just call from that variable anytime i need it thats been my method atleast
While that is better in theory, it doesn’t actually matter that much. The existence of a casting node is what loads other things into memory, not the execution. The existence of a variable will do the exact same. That can be fine, just something to be mindful of :)
sadly unreal's learning materials and documentation kind of suck. what i did to double check if this is all correct is look at how things work in c++. With that you need to add a #include to a class in order to cast to it. that's pretty much what the casting node seems to do too, when it exists in a blueprint, it just adds a #include to that class. So if you want to read up more about that I guess that's a place to look, how #include works and what it actually does.
This is really useful info! I have a lot of experience in other engines and found myself trying to avoid casting in Unreal just because I had seen other people say it. I went as far as starting to cache references in other classes to avoid having to cast again later and now I'm realizing that has memory implications, oops. Definitely going to be diving into the rest of your videos!
"PLEASE just use CASTING" on it's own is bad advice, if it's the only take away people get from this that isn't great. That said this video is actually a pretty good description of how and when to use casting 👍. Two things worth noting: - Re: 9:45. This is true but somewhat misses the point. Assuming you already have a reference to something that you wish to cast to an enemy, an interface eg IDamagable on the enemy will allow you to directly call interface functions on it regardless of its class, in many cases this is preferable as it simplifies shared functionality across different Actors (maybe enemies and players are both damagable despite having different parent classes). - Casting to parent CPP classes is pretty much free and does not cause a hard reference.
yeah, no single sentence will be able to really show the nuances of when casting is a good thing vs a bad thing. If someone sees just the title of this video and goes off that... well, let's just say that shows a deeper issue in their learning methods XD 9:45 though, youre' right. my point here is that people want to avoid casting so much, they come up with a bunch of weird ways to not use the casting node, which end up resulting with still having a hard reference, and weird and messy code on top of that too. (Ie : an interface that returns a reference to said object type, that's just a bad idea). those "solutions" are born from a lack of understanding about what makes casting so bad, people just try to avoid using it because they heard they should, without knowing why. Having seen that happen a fair amount is what prompted me to make this vide in the first place :) small note about the cpp parent class thing : it's not so much that casting to a cpp class is free, more that casting to a shared parent class is free (so a character getting an actor ref and casting it to a pawn is free). but if you have a class that's made in cpp that branches off from actor (let's say something like AItemPickup, which then has a bunch of child classes of it's own, but ACharacter is entirely separate from that inheritance branch), casting to it isn't free just because it is a cpp class. I am sure you yourself understand that! Just pointing it out in case anyone else reads this and misunderstands your meaning :)
@@thegamedevcave Sure, I understand these kind of titles attract an audience and hopefully people are interested enough to listen carefully to your advice. I understand the point you were trying to make about avoiding interfaces, I've also seen the case you mention where people try to avoid a cast an end up with a hard ref anyway because it took a bp as a param or returned one. There really is a difference between casting to a cpp base and a bp though. BPs are assets and as such will require any hard referenced assets be loaded (as you've mentioned). Cpp classes are *not* assets, casting to one or using functions defined in one will not in and of itself cause any other assets to be loaded at the same time as the calling/casting BP. The cast itself to a cpp class is so low cost that ive never seen it have a noticable performance impact. Avoiding asset dependency hell is the primary reason I and many others do tend to stear people away from casting to BPs. It can have very real load performance, memory and compilation time costs. As youve mentioned there are circumstances where it isnt so bad such as casting to assets that you expect to already be loaded, or within a small group of highly coupled bps.The advice I tend to give where I work is if you want to cast, do it to the highest parent class that gives you the functionality you need, and if at all possible that parent should be in Cpp. If someone is getting their feet wet, prototyping or building something small most of this advice is moot, cast away! Just know that there are reasons it sometimes gets frowned upon (that it sounds like you are already well aware of). If anyone is curious to learn more there is a great talk from Sjoerd de Jong here that covers this topic really well. ua-cam.com/video/0YMS2wnykbc/v-deo.html Edited for typos and to correct above link :)
@@hanswannop9541 yeah for sure! blueprints tend to have hard refs to assets. My point was more that that is due to how they are used and not anything inherit about it being a blueprint. but in particle terms you're 100% right. The point of a blueprint is to setup up a class as an asset that's ready for use. But unlike engines like Unity, where you have prefabs, the blueprint itself also is a class, which can lead to this sort of confusion (but also can be amazing since you can add a little extra scripting to a specific blueprint class of course). and yeah, i'm not happy about having to use hyperbolic creaming titles either to be honest. if people would click on video/thumbnails with normal informational content i would much prefer to do that instead. but sadly, you kind of have to trick people into learning sometimes :/
@@thegamedevcave Understood for the titles. Again though a BP acts both as a class (as you mention) but *itself* is an asset which you are making hard ref to if you cast to it. A cpp class is not an asset, this distinction is an an important one when understanding the impact of casting, outside of the valid usage considerations you mention. All the details are in the talk linked. Apologies to be a stickler, its certainly a complex, difficult to teach topic with a lot of *it depends*. Thankyou for your educational work here.
everyone is a noobie at some point and needs to be told these things. especially when there is such a common (blind) sentiment to avoid casting without reason in the unreal community :)
@@thegamedevcave Indeed, i'm just saying it is worth starting with C++ courses because making a significant game will requires a high level of understanding and designing anyway. Things that blueprint never teaches.
@@TeHzoAr I have seen lots of examples where the youtuber says that you need to implement the interface on both classes for them to work. I have seen others saying that interfaces are a communication mechanism. I watched one guy the other day go to the trouble of setting up an interface on a blueprint and then just made a direct call to the underlying method when he wanted to use it! I've seen another where an interface is described as "a way of communicating between actors that is basically a function and an event". I could go on
@@Foxedupuk the official documentation actually suggests both classes need to implement the interface, it's wild. The only reason I understand them is my c# experience
@@Foxedupuk like what is going on here in the official docs: "Interfaces are useful for allowing communication between different Blueprints. Functions from a single interface can be called on other Blueprints. This can be done when 2 criteria are met: Both Blueprints implement the same interface with the required function."
Interesting video. Thanks for your time on this. If I have an enemy that I need to cast to the player for some interaction, do I actually save anything by doing the casting only once on the enemies Begin Play, then making it a variable? I'd think I would. And yes I should be using interfaces and I do but for something like move the enemy character to the player I need to know the player to get his position. I suppose I could send the player's transform to the Game Mode? or maybe the level manager?
casting once and saving that as a variable doesn't actually save all that much. the operation to do the cast isn't very expensive at all, the issue with casting is that it created the hard reference, meaning that it will always load the cast to class along with the class that does the casting, along with any other assets hard referenced in that. So only casting once doesn't really fix that issue. That said, casting from an enemy class to your player class is generally fine for performance (not great practice still of course but sometimes it's just easier to cast). Because your player is always loaded anyway. But the other way around, your player casting to an enemy class, that could be an issue, at least once you scale up a game and you suddenly have to cast to a bunch of different enemy classes. So if you find yourself casting TO the player, you're probably fine. If you find yourself casting FROM the player, that might point to an issue in how your code operates. that said, for what you describe here, getting the player's position you shouldn't need to cast. You can get actor position from any sort of actor reference so jsut using the "get player character" function or even get player pawn, you can just get the position straight from that, no need to cast to anything for that. casting is only needed if you need to access something that only exists on a specific class, you can always just operate with reference variables of parent class types (like Actor,Pawn and Character, rather than specific blueprint classes like BP_ThirdPersonCharacter for instance)
@@thegamedevcave Thank you. That makes perfect sense. I try to use an interface anytime I have any type of interaction. (I'm watching all your tutorials).
I've seen so many people use an interface function with an isvalid macro to get a blueprint reference. like bro, you're literally casting with extra steps 😪
Hi, can you make a video for using hand ik to "grab an item" at a dynamic location? (Like, the hand automatically stretches and aims at the item regardless of the position) Thanks
In the condition that the class being casted is needed all the time, I always cast on the "begin play" event, and promote the return value as a variable. Then use it anytime. Is this a good practice or not. We should avoid casting per call right?
Its slightly better but not that much, the issue with casting is memory related because it creates a hard reference. Casting only once or even having an object reference varoable of a certain type still creates that hard reference. So casting once in begin play and then keeping it as a variable, while good form.. doesnt actually adress the main issue
holly cow i feel like im not insane anymore ever since i started using unreal i was always like why the heck do people hate casting its so quick and easy and doesn't affect performance that bad unless you are using it on each tick so i finally feel like im not insane for thinking this
the cost isnt' actually based on how often you run the casting node, throwing it in tick (while needlessly re-running the cast, which is of course not great) won't actually effect you a lot. the existence of the casting node in the first place is what is (or rather, what can be) expensive due to it creating hard references and loading a bunch of stuff into memory that may not be needed in memory at that time. If youre casting to things that are already loaded ( they exist in the level already or are loaded due to hard references by other actors), the main issue with casting isn't actually an issue. it's a pretty tricky thing sometimes to figure out when a cast is or isn't okay because of all that, a lot of people just go "well casting is bad. end of story" because of that.
😅 i like to keep my memory usage small and my code flexible so my rule is if i need to chain casts or if the thing I'm casting to may not always be loaded ill use interfaces or didpatchers but i think like most thing its a tool you just need to know how to use
yeah for sure, dont JUST use casting, people going around telling everyone to avoid casting comes from the issue of people overusing casting and not understanding it. It's all about knowing what the impact is of the choice of tool you make :) if that impact is very small and you can use a cast, you should feel free to cast to something. Just have to be careful about it but don't need to entirely avoid it :)
oh there for sure, you should 100% use an interface. not just for performance reasons either in that case. in these situations it's legit more painful to stack a whole bunch of casts. just sending out an interface message is so much easier when you find yourself doing that :)
Funny how I just got recommended a video warning exactly against casting and to use something else that I forgot the name of. To be fair, it is a bit suspicious that so many tutorials just do casting.
probably wanted you to use interfaces. which is a good tool to have, it's so much more useful in many cases! But it's not a 100% replacement for casting at all times :) sometimes a cast is straight up okay to use :) ... just dont go casting to everything all the time
so i guess as a summary use cast when: it is a thing that for example a npc or your character creates anyway and use interface when it is part of the npc but you don't want to load it every time a npc or player spawns. sounds ok?
more or less. It's more like knowing what parts of your game always belong together and what parts can also exist seperatly. if they can exist seperate from eachother, use things like itnerfaces toprevent hard referencing. if they always exist together anyway, cast as much as you'd like to those things. (which is why casting to the player class 99/100 times is fine because the player is always loaded anyway, since.. well, it's the player). if the NPC you're talking about is an enemy that appears once in your game, definitely prevent hard references, but if it is a 2ndary character that's always with he player ( like sonic and tails in the old sonic games), you're safe to cast.
i mean, yeah that's generally the most accurate info but unreal is pretty famous for having a real painful lack of learning materials. But for sure, it should be the first place you check stuff when you have questions in the off chance they give any useful info
Thanks for this video. This will save me a lot of time. I'm just wondering about something. Does a cast reload a class into memory if it's already loaded. I'm hesitated to use casts in functions that will be used many times like in behaviour trees because of the compute effort needed to reload it.🤔
the cast itself on execution doesn't load anything, it is the existence of the node in the first place that loads in the other class. which is the tricky but. even if you have a casting node somewhere in your blueprint that rarely gets triggered, that other class is still being loaded in the moment you spawn in the actor that does the casting. I believe it's even so bad that a casting node that's disconnected from anything will load other classes in. But once that's all loaded in, the actual execution of the cast node is.. well not free of course, limiting any unneeded repeating of code is probably a good thing, but it's not really something to worry about with the cast node.
9:20 random nitpick, but would it be a good idea to name behaviour tree tasks after the family of objects they are made for (especially if they need to cast to that object)? So things like BTTask_EnemyDoAbility or BTTask_DoAbility_AsEnemy. As an idiot, I am a strong advocate for writing idiot-proof code.
yeah if your ability relies on a cast and as such is limited to be used on only specific ai pawns, it's probably good to idiot-proof it by naming is accordingly :)
But it will not load whole object including all meshes inside of Blueprint, it load basically just classes, right? Ten I would tell that I should not care about, until it not loading really assents like meshes, animations, textures, etc. If it load just comilet classes with methods, right? But eyes, sometimes even class can be huge, but still not 200 MB character mesh.
if a hard reference loads another class with a hard reference ( like a default value of a mesh, like most blueprints have) then the WHOLE thing gets loaded in. That's also why using soft object references where you can is better (especially to assets like meshes) because then if you do need to load in the class, it won't drag all the other things into memory right away too :)
@@indiesigi7807 casts cost the exact same in blueprint that they do in c++. while in editor, blueprint nodes have a little extra overhead, once compiled into a game, blueprints get translated into c++ classes anyway. The cost of a casting node is the need for adding a #include in the c++ class. So, yeah the execution of the cast itself is pretty cheap (not free, but it might as well be). it's the memory of including that other class that is the real cost, which is true in both cases.
@@thegamedevcave This is quite sad. I would really expected that mesh itself will be loaded only if there is required to show it in the level on the screen :-(.
So you're saying it's perfectly fine to "cast back and forth" within the same character -- but then why even do that, when you can just cast once on Blueprint Initialization, and save into variables all those references you'll need later? Then no more need to cast back and forth and make the BP more complex than it needs to be... Unless... is there anything I'm overlooking about storing those references on initialization which in your opinion would make it a problem down the road, or create limitations?
the cost of casting isn't running the actual casting node, the thing that makes casting expensive is the fact that you're creating a hard reference to another class/ asset. once that hard reference is in place, running the actual casting node itself is negligible in performance cost. so casting once and saving it as a variable, while better in theory, still doesn't actually save you anything really. The point i'm making here is that you can create hard references (most often in the form of casting) between 2 classes that always belong together without is actually costing anything. The idea that the execution of the casting node is expensive is a misconception, it's the existence of it in the first place which is (or at least can be) expensive
@@thegamedevcave Yeah granted that was a bit besides the point you were trying to make, sorry I think I got stuck on "back and forth" -- I guess if anything, variables help to declutter the BP, even if they don't actually contribute to any perf improvement. Although let me ask you a question about casting + storing a class instance reference: if you cast only on BP Initialize, and store that hard reference into a variable, are you storing a "snapshot" of the instance at the time of initialization, or are you indeed saving a reference in the sense that when you access that variable later at runtime, the instance it points to will have been updated by whatever process altered it since initialization?
al object references (blue variables) are pointers, so they just point to an instance and will always reflect it's current state. if you want to "snapshot" something on any actor you need to store whatever info you're trying to snapshot inside a variable of its own ( so if you want to snapshot a float for it's health, you would have another float on whatever actor is doing that snapshot to store that value in)
The biggest problem with casting is it loads a COPY of everything into reference, not a pointer. It's pretty easy to just use the memory tools to see that casting causes huge problems in games with any actual size. Indie games are small so it doesn't really matter, but in a AAA studio, you'll see it avoided like the plague for a reason.
i've heard things like this be said but I haven't found anything to support this. As far as I know using a cast or making a hard ref makes a #include on the c++ level. as far as I am aware, includes don't just dump the whole memory footprint of one class on top of another class. it will increase a bit, because definitions need to be stored of course but it doesn't copy the whole class over with it's entire memory footprint. Unless i am missing something. If you have some place for me to read more about this if I am missing something please do let me know and i'll try to make sure to include any updated info in the pinned comment :)
@@thegamedevcave yes IT DOES NOT copy the full memory allocation, the OP is incorrect. Thats why he works in AAA they know nothing but how to lie to make delays and push back deadlines, sry but we are not your project mananager you dont need to BS us... lmfao. Anyways after getting my distain for AAA out of the way there are plenty of ways you can test this in engine at any time. UE is smart enough to not just keep allocating memory to the same thing over and over. GG
yup that's actually how I normally work with it. I use cast every time I can and also instead of functions I make custom events so then when I feel like I have everything I need I change to interfaces and it's pretty easy to replaces most stuff
Unfortunately, this is again propagating incomplete info. The reason why it's correct to tell people to avoid casting, is because the people that are the targets of that statement are the ones most likely to be harming themselves. Performance isn't the only factor to consider, it's just the one used to scare people away from casting the easiest. Avoiding casting is a principle of good software design and development. People that understand how to design software, understand when a piece of code is one off, unchanging, and will never ever need to be used or copied anywhere else are the ones that know when a hardcoded type reference is appropriate. And contrary to the message of this video: it's almost never appropriate. We don't teach people to write crap code, we teach them to protect themselves. And once they've learned what they've been protecting themselves from they take off the training wheels on their own. And you can say, 'I'm never going to need to write unit tests or share my code with other projects or people, I'm allowed to write crap code if I want to." And you'd be right. Everyone is allowed to write crap code. But why waste our time teaching them how to do it? Can you imagine how many people you're going to Dunning Kruger into thinking they know when hardcoded type references are OK? Including yourself.
people are scared into not using casts because yeah, if you use casts without understanding what they do your code will be pretty shit. but then they end up avoiding casting all together, still without an understanding of what it does and why they're avoiding it so they didn't really learn anything. "just avoid it" isn't a solution that anyone learns anything from.
@@thegamedevcave It's not a solution, its training wheels for the most basic of people. Telling them not to use the training wheels is the only thing those people will get out of this video. But my question to you is: regardless of performance, do you understand why you should still avoid casting?
@@thegamedevcave I'll take that as: you don't know why it's still a problem, but you choose to speak like an authority on it anyway. I don't have a problem with people expressing their opinions. But it's sad to see the less knowledgeable eat it up as fact, thinking they learned everything. If you really want to reduce misinformation and tell people the full truth I have respect for that. I'm letting you know: this video completely fails at that. Read up on good software practices and have another go. Or don't and make your money anyway, we both know which one is easier.
@@nichan008 no i'm just not wasting my time arguing with you because we clearly are coming at this from 2 different directions. I can respect your dedication to making sure no misinformation is spread. This video is aimed specifically at people who avoid casting because theyve been told "casting bad" without any nuance or more importantly, reasoning as to why. If someone takes this video as the other extreme and goes "oh so i can just be wasteful and cast all over the place" that' not really my fault at that point. There's always going to be people who try to simplify information and with that misinterpreted it. All i'm doing here is shining the slightest bit of nuance on a topic that many beginners take way too literally. and with that, unless you have anything more of value to add, i think this discussion is pretty much over now.
For 70% off + 3 months free NordVPN here : nordvpn.sjv.io/TCG
I feel like these videos on how engine functionality actually works are an incredibly valuable thing. There's so much cryptic half-information and guesswork out there that getting a coherent understanding by yourself is a pretty laborious task.
You are 100% correct as it is quite laborous but the returned value is exponential compared to the applied effort. Understanding if things are possible or better put, scalable or if there might be more unknowns preventing success (such as needing double floating point back on UE4) are worth their weight in gold. It's one thing to waste a bit of time as shown in the video by doing extra interface stuff, but another matter entirely to have to rebuild a feature all over again after determining a roadblock with the engine in one way or another due to incorrect expectations of how something works. It's an invaluable skill that often comes with more and more experience and bigger projects & the concept applies to any software really
It's open source mate, free to look into it.
@@arnaudkaho7137 because someone watching tutorial content mainly targeted at hobbyists/beginners will most definitely know how to look into engine code and be able to understand it.
source available*
@@nubunto 🤔
A good analogy could be like when you tell children to stay away from fire. Fire can be very dangerous when handled improperly, and children are just too inexperienced to explain, and be expected to retain, when it's safe and when it's not safe to use it. So to avoid any chance of it becoming a hazard, you warn them to stay away from it completely. Which is why I get why people say to avoid casting. But like fire definitely has its uses, there are many many uses for casting, and eventually you'll mature enough to understand how to be responsible with it.
Thats a wonderful way to explain it!
There are reasons it exists; reasons Epic actually put it in the Engine. Every project ever, has casting to some degree.
The problems are way less pronounced today. By 2025 ish, its predicted the majority of PC consumers will have at least 32 gigs of ram. Consoles already have 32+ gigs of ram. Its extremely hard for an indie to work at a scale where the pitfalls of casting will actually apply.
When you work on large projects that have asset linkers, Data Assets like DA_CharacterAudio or a game like Fortnite, literally thousands of potential skeletal mesh skins. You need ways to load assets in and out without referencing the entire asset tree.
Incorrect Casting there will literally prevent most players from being able to play due to lack of memory or ungodly load times with linking like 10 gigs of audio directly to a player character needlessly.
But you are right. For most people? Most devs? Most projects? What they are Casting to will already exist in their game anyway. Its already loaded and therefore has virtually zero cost. Casting can also prevent hitching common in a lot of titles by just hard linking related gameplay assets.
oh for sure! dont just randomly cast to a bunch of stuff without knowing that it also loads in a bunch of assets.
and even though i'm advacating for using a cast every now and then, i still think setting up an interface call makes more since 9/10. people are just unreasonably affraid of casting and don't actually make any consideration for it as a result.as you say, for most people, they're working on a scale where even if they do mess things up, it doesn't actually hurt all that much with modern computers having more and more memory .
I wanted to throw my hat into the ring as well, but decided not to. Casting is indeed fine, issue arises when you cast to things not loaded in memory. So if that is an issue, you can circumvent this by casting to base classes instead, which you can setup with the basic skeleton functionality you want, drastically reducing the potential spike in memory used.
I used to do interfaces all the time for literally everything, then I realized I was adding unnecessary overhead to the program. Interfaces are good for when you want to share functionality in different classes. It took me a while to realize this, and I only figured this out when I started using the C++ side. A tool is only as good as how it is used. Sometimes casting is better, sometimes interfaces are better. Interfaces can add unnecessary complexity to your code if used incorrectly, which I have done a lot. This is ignoring that under the hood, calling an interface function results in a cast anyway. So if casting is bad, then so are interfaces.
As a general rule, if it's only ever going to be one class, use inheritance to your advantage and cast, if you are going to use different unrelated classes (for whatever reason) use interfaces.
That said I still like using interfaces, if I think there might be future use for it. The cost is generally low either way if used correctly.
i think this is pretty much spot on. casting is fine, but shouldn't be a crutch in situations where it noticeable harms performance. it's 1 tool in a wide toolbelt that has it's own usefulness within it's own context.
in general overdoing interfaces will do less harm than overdoing casting so i get that a lot of people want to be on the safe side and avoid casts altogether. I personally think "X is bad" should be a mindset that we avoid, "X is bad at Y and shouldn't be used for Z because of that" is good though. :)
Came here to post the same thing. To put a fine point on it: avoid casting against blueprints, which will always load every part of the blueprint into memory if it isn't already, which is why casting against base classes is the right way to go. (Source: I was casting against an NPC BP once and absolutely wrecked perf on debug builds of the editor.)
So refreshing to get real explanations. Your videos have helped me understand so many things in the engine from “why” instead of just “how.” More of these please!
I thought the dependency of casting is not recommended when it's used to access a class of a general actor/object reference, instead an interface can be used, because it's easier to maintain.
An example is the magnet ability in Zelda BOTW, when it's activated all metallic objects glow and are selectable. Traditionally, all those objects would be children of the same Metallic Object class, so, when they are selected you need to cast to the parent class. Then let's say Nintendo bought an asset from the marketplace which contains ready to use metallic weapons, but they are not children of the metallic object base class, then, they need to re-write the objects instead of just implementing an interface on them
yes, for a lot (by far most) cases setting up your code to use interfaces will both preform well and be easier to scale up in scope.
Certainly don't throw casts all over the place but if you understand what the actual downsides of a cast are, you can also decide when they are worth using.
For the example you give here, the player class doesn't need (and shouldnt) to know about every single possible object to interact with so it just uses an interface and lets the object itself figure things out. That way, specific objects can also easily implement their own unique code when interacted with.
Now instead, let's say we have a weapon and that weapon needs to know some of the player's stats in order to do something (assumeing damage calculation is done on the weapon). there is no real harm in casting from the weapon to the player here, since the weapon is never going to exist without the player and the weapon simply needs to access a variable that exist on the player. Now, that does mean that this weapon now can only be used by the player but if you design your code with a bit of forsight, you probably would have a parent class "Combatcharacter" or something like that, which has all the combat related values on it, and you can cast to that instead, now it will also work on any other class that inherits from "CombatCharacter" and there's no real downside to it anymore.
about 95/100 times interfaces will end up being smoother to work with and better for memory, but those 5/100 times that they're not, it's dine to use a cast if you know when to :)
This gentleman is absolutely right!
A wonderful easy explanation about why casting is a real feature and it has a reason to exist. It has its benefits and weak points.
So, yes use casting if you know that object is already loaded ... Game instance for example, always loaded
Thanks for clarifying this topic and for sharing!
I think the reason why people say not to use casting is because it's easy to get out of hand really quickly with dozens of cast nodes, and for the most part, there isn't a need to cast. If you're trying to check to see if the overlapping actor is the player for example, you can use tags which doesn't create a dependency. If you're trying to call a function, you can use an interface, and if you're trying to communicate between actors, you can use dispatchers. The original Epic tutorials told everyone to use Event Tick and Casting because they saw blueprint as something you only use for prototyping, and a lot of the official tutorials were written by artists and not programmers. It's not a rule of Never use casting. It's more, avoid it if you don't need to use it because it's just lazy programming and unnecessarily eats up memory. In your own example of casting to the Reaper class when you're using that ability, imagine the scenario where the Reaper is spawning a dozen projectiles, so you're just casting from the projectiles to the Reaper, because as you said, the Reaper is the parent. But now imagine that the Reaper shoots the 12 projectiles and then immediately dies to the player's attack. Those 12 projectiles are all storing the Reaper in memory even though he's likely been destroyed. So not only is it a waste of memory, but also you're going to get errors when you stop playing due to the projectiles trying to reference something that doesn't exist anymore. This causes instability and creates a greater chance of your game crashing for unknown reasons. It's just a bad habit to get into.
i totally get this, but the advice of " avoid casting and event tick" is taken as a hard and fast rule by a lot of people who don't actually understand the "why" behind that advice , i see it pop up in a lot of places online and i figure that having a little bit more content and info out there going into the nuanced rather than just "spam casting, because it's easy" and "casting is literally the devil's work" will be good for people to learn how things work and when certain choices do and do not have a relevant impact.
as far as the reaper example goes, those projectiles will also be gone in a handful of seconds so even if the reaper class stays in memory for that little time longer, that's really not an issue.
literally just went through a huge decoupling process and at the end of it all i realised i could have just casted in so many places as many things were already loaded a lot of the time e.g player controller, player character, game mode etc
oof that is painful XD but hey, it's better to know HOW to decouple things than not know how to do it at least, so that's an upside :)
but yeah sometimes a quick and dirty cast will save you your sanity and not actually cost anything XD
Yes sadly because of misinformation its easy to not realize that EVERYTHING in your level is in memory already... The ONLY things u dont want hard refrenced is things that are not always in the level or in every level. If you have a 1 player character game with 1 Level you can litterally hard ref everything otherwise you need to use soft refs and plan accordingly
Solid video, and I agree. Some casts have to happen, like I open loading a level by casting to game_instance which I use as a reference container. There is literally no way to get the GI other than a cast. However, I do try and leap frog references as much as possible to minimize casting but a few casts to get gi, game mode, player char is totally fine.
yeah GI is another one that's pretty much a free cast. everything in your game already exists in your game instance, so unless youre casting to a GI class that you're not using which... why would you? youre pretty much free to cast to your GI anytime you want ( i mean, within reason of course xd)
@@thegamedevcave Ya, you can't even change GI mid game not sure why you would ever have 2.
The correct answer is to avoid casting if you can, but use it if you would otherwise need to jump through hoops to not use it. And don't feel bad about it.
yup that's prety much it! :)
Thanks! This is a great explanation of the topic. Love hearing why and how it all works, rather than following weird rules blindly.
You're very welcome!
I like how I just watched a video from your channel called "STOP casting!"
both sides of the arguments are important to hear, you need to learn about why casting is bad, but also that you can use it when it makes sense.
too many people learn about the downsides of casting and go into a "NEVER EVER CAST EVEN IF MY LUIFE DEPENDS ON IT" mindset, which is way too far in the other direction XD
@@thegamedevcave I think the titles of the videos are getting in the way of the message. Both videos are basically about the same thing: when to use casting and when not to. The content of both videos are great, but I think the titles could be a little more descriptive.
A thing i just figured out is that you can connect the variable of the cast to the object pin 😅
Very nice video!
I've always had this feeling casting is being injustice in some situations.
I hope beginners find your videos before others because man, the guys that rank when searching back when I watched tutorials, looking back now, are the worst.
matt assbland and gorka games in particular are literally "how to ue5 worst practice"
LOL. This is correct. I like to say it makes a difference whether you are casting to a sardine or whale. I think one video in particular freaked everyone out because the argument on why it was bad was compelling, but then it should have been clarified that there are times when it is, as you say, perfectly fine.
that's actually a fantastic way to say it, i'm totally going to take that saying and use it in the future!
So to clarify, to save time or if there's no other option then use casting if both 'objects' are loaded into the level anyway. Such as actors in the level, game mode, level blueprint etc..
And that 'get actor of class' is the same cost as casting.
I've been using interfaces in pretty much every situation I can but I came across a time I absolutely needed to cast to then use my interface to carry across variable data. Odd situation but it worked lol
Pretty much, get actor of class has the same memory implications as a cast (so does simply having a reference variable of that type) but get actor of class also is rather expensive to execute on top of that.
@thegamedevcave so get actor of class is more costly than casting? Might have to rethink some of my code...
@@MonsterJuiced yeah by a pretty significant amount, what it does ( more or less) is try all actors 1 by 1 to see if they're of that class ( so, casting pretty much) and once it has found one it returns a reference to that.
it still creates the hard reference that is the main issues with casting to begin with, but also takes up computing power to find an actor in the first place. it's not as bad as "get all actors of class" that one is even more expensive but it's still not something you'll want to be doing often or on a large scale.
You can run a check / graph to see how heavy the load for casting is. I can’t remember it off the top of my head, but it will show exact memory usage of all the references you are calling with the cast. If you get a lot of nested ones it can be expensive. I imagine it’s more important later on with regards optimisation, I still think interface is the way to go.
I am a professional game developer working in Unreal for a decade, and I FULLY endorse the message.
All points are spot on.
I usually cast a reference once at begin play convert it to a variable then i just call from that variable anytime i need it thats been my method atleast
While that is better in theory, it doesn’t actually matter that much. The existence of a casting node is what loads other things into memory, not the execution. The existence of a variable will do the exact same.
That can be fine, just something to be mindful of :)
Is there any documentation you sourced this from? Would love to read more about it
sadly unreal's learning materials and documentation kind of suck.
what i did to double check if this is all correct is look at how things work in c++. With that you need to add a #include to a class in order to cast to it. that's pretty much what the casting node seems to do too, when it exists in a blueprint, it just adds a #include to that class. So if you want to read up more about that I guess that's a place to look, how #include works and what it actually does.
This is really useful info! I have a lot of experience in other engines and found myself trying to avoid casting in Unreal just because I had seen other people say it. I went as far as starting to cache references in other classes to avoid having to cast again later and now I'm realizing that has memory implications, oops. Definitely going to be diving into the rest of your videos!
Glad it was helpful!
"PLEASE just use CASTING" on it's own is bad advice, if it's the only take away people get from this that isn't great. That said this video is actually a pretty good description of how and when to use casting 👍. Two things worth noting:
- Re: 9:45. This is true but somewhat misses the point. Assuming you already have a reference to something that you wish to cast to an enemy, an interface eg IDamagable on the enemy will allow you to directly call interface functions on it regardless of its class, in many cases this is preferable as it simplifies shared functionality across different Actors (maybe enemies and players are both damagable despite having different parent classes).
- Casting to parent CPP classes is pretty much free and does not cause a hard reference.
yeah, no single sentence will be able to really show the nuances of when casting is a good thing vs a bad thing. If someone sees just the title of this video and goes off that... well, let's just say that shows a deeper issue in their learning methods XD
9:45 though, youre' right. my point here is that people want to avoid casting so much, they come up with a bunch of weird ways to not use the casting node, which end up resulting with still having a hard reference, and weird and messy code on top of that too. (Ie : an interface that returns a reference to said object type, that's just a bad idea). those "solutions" are born from a lack of understanding about what makes casting so bad, people just try to avoid using it because they heard they should, without knowing why.
Having seen that happen a fair amount is what prompted me to make this vide in the first place :)
small note about the cpp parent class thing : it's not so much that casting to a cpp class is free, more that casting to a shared parent class is free (so a character getting an actor ref and casting it to a pawn is free). but if you have a class that's made in cpp that branches off from actor (let's say something like AItemPickup, which then has a bunch of child classes of it's own, but ACharacter is entirely separate from that inheritance branch), casting to it isn't free just because it is a cpp class. I am sure you yourself understand that! Just pointing it out in case anyone else reads this and misunderstands your meaning :)
@@thegamedevcave Sure, I understand these kind of titles attract an audience and hopefully people are interested enough to listen carefully to your advice. I understand the point you were trying to make about avoiding interfaces, I've also seen the case you mention where people try to avoid a cast an end up with a hard ref anyway because it took a bp as a param or returned one.
There really is a difference between casting to a cpp base and a bp though. BPs are assets and as such will require any hard referenced assets be loaded (as you've mentioned). Cpp classes are *not* assets, casting to one or using functions defined in one will not in and of itself cause any other assets to be loaded at the same time as the calling/casting BP. The cast itself to a cpp class is so low cost that ive never seen it have a noticable performance impact. Avoiding asset dependency hell is the primary reason I and many others do tend to stear people away from casting to BPs. It can have very real load performance, memory and compilation time costs.
As youve mentioned there are circumstances where it isnt so bad such as casting to assets that you expect to already be loaded, or within a small group of highly coupled bps.The advice I tend to give where I work is if you want to cast, do it to the highest parent class that gives you the functionality you need, and if at all possible that parent should be in Cpp. If someone is getting their feet wet, prototyping or building something small most of this advice is moot, cast away! Just know that there are reasons it sometimes gets frowned upon (that it sounds like you are already well aware of).
If anyone is curious to learn more there is a great talk from Sjoerd de Jong here that covers this topic really well.
ua-cam.com/video/0YMS2wnykbc/v-deo.html
Edited for typos and to correct above link :)
@@hanswannop9541 yeah for sure! blueprints tend to have hard refs to assets. My point was more that that is due to how they are used and not anything inherit about it being a blueprint. but in particle terms you're 100% right. The point of a blueprint is to setup up a class as an asset that's ready for use. But unlike engines like Unity, where you have prefabs, the blueprint itself also is a class, which can lead to this sort of confusion (but also can be amazing since you can add a little extra scripting to a specific blueprint class of course).
and yeah, i'm not happy about having to use hyperbolic creaming titles either to be honest. if people would click on video/thumbnails with normal informational content i would much prefer to do that instead. but sadly, you kind of have to trick people into learning sometimes :/
@@thegamedevcave Understood for the titles. Again though a BP acts both as a class (as you mention) but *itself* is an asset which you are making hard ref to if you cast to it. A cpp class is not an asset, this distinction is an an important one when understanding the impact of casting, outside of the valid usage considerations you mention. All the details are in the talk linked. Apologies to be a stickler, its certainly a complex, difficult to teach topic with a lot of *it depends*. Thankyou for your educational work here.
This makes so much sense. Good stuff man
Very clear explanation, now I can use casting on my game with peace of mind xD
Learn C++ guys... this is a noobie issue.
It's all about hard reference, if you don't know that you missed the very first step of programming.
everyone is a noobie at some point and needs to be told these things. especially when there is such a common (blind) sentiment to avoid casting without reason in the unreal community :)
@@thegamedevcave Indeed, i'm just saying it is worth starting with C++ courses because making a significant game will requires a high level of understanding and designing anyway. Things that blueprint never teaches.
@@arnaudkaho7137 for sure, learning c++ will improve understanding of what is ACTUALLY happening so much
is it okay to use casting on every actor classes, such as Door, Key and so on. I need character reference there and need some parameters to get it ??
This is the same as the youtubers showing you how to use interfaces and then using them wrong. The amount of misinformation about them is crazy.
do you have examples of how they suggest using them wrong? just using them to implement one function/event?
@@TeHzoAr I have seen lots of examples where the youtuber says that you need to implement the interface on both classes for them to work. I have seen others saying that interfaces are a communication mechanism. I watched one guy the other day go to the trouble of setting up an interface on a blueprint and then just made a direct call to the underlying method when he wanted to use it! I've seen another where an interface is described as "a way of communicating between actors that is basically a function and an event". I could go on
@@Foxedupuk the official documentation actually suggests both classes need to implement the interface, it's wild. The only reason I understand them is my c# experience
@@Foxedupuk like what is going on here in the official docs:
"Interfaces are useful for allowing communication between different Blueprints. Functions from a single interface can be called on other Blueprints. This can be done when 2 criteria are met:
Both Blueprints implement the same interface with the required function."
Interesting video. Thanks for your time on this. If I have an enemy that I need to cast to the player for some interaction, do I actually save anything by doing the casting only once on the enemies Begin Play, then making it a variable? I'd think I would. And yes I should be using interfaces and I do but for something like move the enemy character to the player I need to know the player to get his position. I suppose I could send the player's transform to the Game Mode? or maybe the level manager?
casting once and saving that as a variable doesn't actually save all that much. the operation to do the cast isn't very expensive at all, the issue with casting is that it created the hard reference, meaning that it will always load the cast to class along with the class that does the casting, along with any other assets hard referenced in that.
So only casting once doesn't really fix that issue. That said, casting from an enemy class to your player class is generally fine for performance (not great practice still of course but sometimes it's just easier to cast). Because your player is always loaded anyway. But the other way around, your player casting to an enemy class, that could be an issue, at least once you scale up a game and you suddenly have to cast to a bunch of different enemy classes. So if you find yourself casting TO the player, you're probably fine. If you find yourself casting FROM the player, that might point to an issue in how your code operates.
that said, for what you describe here, getting the player's position you shouldn't need to cast. You can get actor position from any sort of actor reference so jsut using the "get player character" function or even get player pawn, you can just get the position straight from that, no need to cast to anything for that. casting is only needed if you need to access something that only exists on a specific class, you can always just operate with reference variables of parent class types (like Actor,Pawn and Character, rather than specific blueprint classes like BP_ThirdPersonCharacter for instance)
@@thegamedevcave Thank you. That makes perfect sense. I try to use an interface anytime I have any type of interaction. (I'm watching all your tutorials).
I've seen so many people use an interface function with an isvalid macro to get a blueprint reference. like bro, you're literally casting with extra steps 😪
Hi, can you make a video for using hand ik to "grab an item" at a dynamic location? (Like, the hand automatically stretches and aims at the item regardless of the position)
Thanks
This is good stuff, hope it helps some devs somewhere
In the condition that the class being casted is needed all the time, I always cast on the "begin play" event, and promote the return value as a variable. Then use it anytime.
Is this a good practice or not. We should avoid casting per call right?
Its slightly better but not that much, the issue with casting is memory related because it creates a hard reference. Casting only once or even having an object reference varoable of a certain type still creates that hard reference. So casting once in begin play and then keeping it as a variable, while good form.. doesnt actually adress the main issue
holly cow i feel like im not insane anymore ever since i started using unreal i was always like why the heck do people hate casting its so quick and easy and doesn't affect performance that bad unless you are using it on each tick so i finally feel like im not insane for thinking this
the cost isnt' actually based on how often you run the casting node, throwing it in tick (while needlessly re-running the cast, which is of course not great) won't actually effect you a lot. the existence of the casting node in the first place is what is (or rather, what can be) expensive due to it creating hard references and loading a bunch of stuff into memory that may not be needed in memory at that time.
If youre casting to things that are already loaded ( they exist in the level already or are loaded due to hard references by other actors), the main issue with casting isn't actually an issue.
it's a pretty tricky thing sometimes to figure out when a cast is or isn't okay because of all that, a lot of people just go "well casting is bad. end of story" because of that.
Very clear explanation - thank you.
Glad it was helpful!
Thats hilarious to imagine every interactible being loaded just because you're playing the game as the main character!! Haha
yeah probably good to avoid that XD
😅 i like to keep my memory usage small and my code flexible so my rule is if i need to chain casts or if the thing I'm casting to may not always be loaded ill use interfaces or didpatchers but i think like most thing its a tool you just need to know how to use
yeah for sure, dont JUST use casting, people going around telling everyone to avoid casting comes from the issue of people overusing casting and not understanding it.
It's all about knowing what the impact is of the choice of tool you make :) if that impact is very small and you can use a cast, you should feel free to cast to something. Just have to be careful about it but don't need to entirely avoid it :)
If I would have to put it into a rule of thumb: "if you have multiple casting nodes in an if/else manner, casting might not be the best tool to use".
oh there for sure, you should 100% use an interface. not just for performance reasons either in that case. in these situations it's legit more painful to stack a whole bunch of casts. just sending out an interface message is so much easier when you find yourself doing that :)
Substantially do not "Abuse" of it.
love that, you can use it, just dont abuse it!
Funny how I just got recommended a video warning exactly against casting and to use something else that I forgot the name of. To be fair, it is a bit suspicious that so many tutorials just do casting.
probably wanted you to use interfaces. which is a good tool to have, it's so much more useful in many cases! But it's not a 100% replacement for casting at all times :) sometimes a cast is straight up okay to use :) ... just dont go casting to everything all the time
so i guess as a summary use cast when: it is a thing that for example a npc or your character creates anyway and use interface when it is part of the npc but you don't want to load it every time a npc or player spawns. sounds ok?
more or less. It's more like knowing what parts of your game always belong together and what parts can also exist seperatly. if they can exist seperate from eachother, use things like itnerfaces toprevent hard referencing. if they always exist together anyway, cast as much as you'd like to those things. (which is why casting to the player class 99/100 times is fine because the player is always loaded anyway, since.. well, it's the player).
if the NPC you're talking about is an enemy that appears once in your game, definitely prevent hard references, but if it is a 2ndary character that's always with he player ( like sonic and tails in the old sonic games), you're safe to cast.
Thank you!!
What you should be doing is watch videos from Unreal Engine, not random people on the internet.
i mean, yeah that's generally the most accurate info but unreal is pretty famous for having a real painful lack of learning materials.
But for sure, it should be the first place you check stuff when you have questions in the off chance they give any useful info
Thank you for that video!
Thanks for this video. This will save me a lot of time. I'm just wondering about something. Does a cast reload a class into memory if it's already loaded. I'm hesitated to use casts in functions that will be used many times like in behaviour trees because of the compute effort needed to reload it.🤔
the cast itself on execution doesn't load anything, it is the existence of the node in the first place that loads in the other class. which is the tricky but. even if you have a casting node somewhere in your blueprint that rarely gets triggered, that other class is still being loaded in the moment you spawn in the actor that does the casting.
I believe it's even so bad that a casting node that's disconnected from anything will load other classes in. But once that's all loaded in, the actual execution of the cast node is.. well not free of course, limiting any unneeded repeating of code is probably a good thing, but it's not really something to worry about with the cast node.
Thanks for the answer! By the way, are you Dutch? I'm just curious because of the accent 😅
@@tijmdevries2222 yupp!
this video is GOLD
Yeah i cast...never had a problem with it so far...
9:20 random nitpick, but would it be a good idea to name behaviour tree tasks after the family of objects they are made for (especially if they need to cast to that object)? So things like BTTask_EnemyDoAbility or BTTask_DoAbility_AsEnemy.
As an idiot, I am a strong advocate for writing idiot-proof code.
yeah if your ability relies on a cast and as such is limited to be used on only specific ai pawns, it's probably good to idiot-proof it by naming is accordingly :)
thank you
But it will not load whole object including all meshes inside of Blueprint, it load basically just classes, right? Ten I would tell that I should not care about, until it not loading really assents like meshes, animations, textures, etc. If it load just comilet classes with methods, right? But eyes, sometimes even class can be huge, but still not 200 MB character mesh.
if a hard reference loads another class with a hard reference ( like a default value of a mesh, like most blueprints have) then the WHOLE thing gets loaded in. That's also why using soft object references where you can is better (especially to assets like meshes) because then if you do need to load in the class, it won't drag all the other things into memory right away too :)
@@indiesigi7807 If you have hard references to assets they will be loaded even if not used.
@@indiesigi7807 casts cost the exact same in blueprint that they do in c++. while in editor, blueprint nodes have a little extra overhead, once compiled into a game, blueprints get translated into c++ classes anyway.
The cost of a casting node is the need for adding a #include in the c++ class. So, yeah the execution of the cast itself is pretty cheap (not free, but it might as well be). it's the memory of including that other class that is the real cost, which is true in both cases.
@@thegamedevcave This is quite sad. I would really expected that mesh itself will be loaded only if there is required to show it in the level on the screen :-(.
thanks!
So you're saying it's perfectly fine to "cast back and forth" within the same character -- but then why even do that, when you can just cast once on Blueprint Initialization, and save into variables all those references you'll need later? Then no more need to cast back and forth and make the BP more complex than it needs to be...
Unless... is there anything I'm overlooking about storing those references on initialization which in your opinion would make it a problem down the road, or create limitations?
the cost of casting isn't running the actual casting node, the thing that makes casting expensive is the fact that you're creating a hard reference to another class/ asset. once that hard reference is in place, running the actual casting node itself is negligible in performance cost. so casting once and saving it as a variable, while better in theory, still doesn't actually save you anything really.
The point i'm making here is that you can create hard references (most often in the form of casting) between 2 classes that always belong together without is actually costing anything.
The idea that the execution of the casting node is expensive is a misconception, it's the existence of it in the first place which is (or at least can be) expensive
@@thegamedevcave Yeah granted that was a bit besides the point you were trying to make, sorry I think I got stuck on "back and forth" -- I guess if anything, variables help to declutter the BP, even if they don't actually contribute to any perf improvement.
Although let me ask you a question about casting + storing a class instance reference: if you cast only on BP Initialize, and store that hard reference into a variable, are you storing a "snapshot" of the instance at the time of initialization, or are you indeed saving a reference in the sense that when you access that variable later at runtime, the instance it points to will have been updated by whatever process altered it since initialization?
al object references (blue variables) are pointers, so they just point to an instance and will always reflect it's current state. if you want to "snapshot" something on any actor you need to store whatever info you're trying to snapshot inside a variable of its own ( so if you want to snapshot a float for it's health, you would have another float on whatever actor is doing that snapshot to store that value in)
@@thegamedevcave Makes sense, thank you 👍
The biggest problem with casting is it loads a COPY of everything into reference, not a pointer. It's pretty easy to just use the memory tools to see that casting causes huge problems in games with any actual size. Indie games are small so it doesn't really matter, but in a AAA studio, you'll see it avoided like the plague for a reason.
i've heard things like this be said but I haven't found anything to support this. As far as I know using a cast or making a hard ref makes a #include on the c++ level.
as far as I am aware, includes don't just dump the whole memory footprint of one class on top of another class. it will increase a bit, because definitions need to be stored of course but it doesn't copy the whole class over with it's entire memory footprint. Unless i am missing something. If you have some place for me to read more about this if I am missing something please do let me know and i'll try to make sure to include any updated info in the pinned comment :)
@@thegamedevcave yes IT DOES NOT copy the full memory allocation, the OP is incorrect. Thats why he works in AAA they know nothing but how to lie to make delays and push back deadlines, sry but we are not your project mananager you dont need to BS us... lmfao. Anyways after getting my distain for AAA out of the way there are plenty of ways you can test this in engine at any time. UE is smart enough to not just keep allocating memory to the same thing over and over. GG
yup that's actually how I normally work with it. I use cast every time I can and also instead of functions I make custom events so then when I feel like I have everything I need I change to interfaces and it's pretty easy to replaces most stuff
kasting is baaaaad... mmmkeyy...
I pooded.
Unfortunately, this is again propagating incomplete info.
The reason why it's correct to tell people to avoid casting, is because the people that are the targets of that statement are the ones most likely to be harming themselves.
Performance isn't the only factor to consider, it's just the one used to scare people away from casting the easiest.
Avoiding casting is a principle of good software design and development. People that understand how to design software, understand when a piece of code is one off, unchanging, and will never ever need to be used or copied anywhere else are the ones that know when a hardcoded type reference is appropriate.
And contrary to the message of this video: it's almost never appropriate.
We don't teach people to write crap code, we teach them to protect themselves. And once they've learned what they've been protecting themselves from they take off the training wheels on their own.
And you can say, 'I'm never going to need to write unit tests or share my code with other projects or people, I'm allowed to write crap code if I want to."
And you'd be right. Everyone is allowed to write crap code. But why waste our time teaching them how to do it? Can you imagine how many people you're going to Dunning Kruger into thinking they know when hardcoded type references are OK? Including yourself.
people are scared into not using casts because yeah, if you use casts without understanding what they do your code will be pretty shit. but then they end up avoiding casting all together, still without an understanding of what it does and why they're avoiding it so they didn't really learn anything. "just avoid it" isn't a solution that anyone learns anything from.
@@thegamedevcave It's not a solution, its training wheels for the most basic of people. Telling them not to use the training wheels is the only thing those people will get out of this video.
But my question to you is: regardless of performance, do you understand why you should still avoid casting?
@@nichan008 agree to disagree on how to give people information I suppose 🤷🏻♂️
@@thegamedevcave I'll take that as: you don't know why it's still a problem, but you choose to speak like an authority on it anyway.
I don't have a problem with people expressing their opinions. But it's sad to see the less knowledgeable eat it up as fact, thinking they learned everything.
If you really want to reduce misinformation and tell people the full truth I have respect for that. I'm letting you know: this video completely fails at that. Read up on good software practices and have another go. Or don't and make your money anyway, we both know which one is easier.
@@nichan008 no i'm just not wasting my time arguing with you because we clearly are coming at this from 2 different directions. I can respect your dedication to making sure no misinformation is spread. This video is aimed specifically at people who avoid casting because theyve been told "casting bad" without any nuance or more importantly, reasoning as to why.
If someone takes this video as the other extreme and goes "oh so i can just be wasteful and cast all over the place" that' not really my fault at that point.
There's always going to be people who try to simplify information and with that misinterpreted it. All i'm doing here is shining the slightest bit of nuance on a topic that many beginners take way too literally.
and with that, unless you have anything more of value to add, i think this discussion is pretty much over now.
Спасибо за видео ) было полезно
Nice video. im gonna watch all of them now. I just found you sir. Thanks.
-SuperKash999