This video is great. When starting I never understood casting because all the tutorials were so simple and manually targeted. You know the ones, connect door to trigger by directly referencing it from the map (this is not scalable) rather than building a door + trigger that can be retargeted etc. Because of this I learnt interfaces and event dispatchers before I understood how to use casting. Turns out this was a pretty good move. You explain things very well.
So, having a variable referencing a actor or casting to it directly in the blueprint consumes more memory but is faster, while soft referencing that same object consumes less memory but takes some time to access it. After all this time, I finally learned how to use soft references, thank you.
@@UA-camAccountManmaybe for character or weapons skins? You may have hundreds in a game and so they are loaded from a soft reference. There may be a fuzzy transition texture to show the skin is updating if it takes a second to load?
This is a misleading understanding of the problem. If you cast to another class, it is ALWAYS loaded when any instance of your own class is. Say you cast to "OpenWorldLevel" to get the time of day, as an example. And you do this from a "timer" widget that just displays a clock. If you ever load that timer widget, it must first load OpenWorldLevel, and every asset that OpenWorldLevel depends on, before the timer can be loaded. Your 3Kb timer becomes a 500MB or even several GB asset. This is a very extreme case, indicating what happens when you've got dependancy chains everywhere. But it is exactly what you end up with when following a typical UA-cam tutorial: Every class casts to every other. And so, to load anything, you have to load everything. And you end up wondering why you're eating 18GB of RAM in an empty level when you try refactoring later. Right click an asset in the content browser, and select "Size Map." At the top right, select the Memory option (not disk size.) This will explain a lot in a few seconds.
There is a mistake @11:51. This will cause an error or crash in a packaged game (or on a restart of the editor). It only works in your example because the editor has it loaded in memory due to GC not having been run yet. If you use Async you MUST use completed to ensure no errors. If you Load Asset Blocking you can avoid and async call and just delay in the frame (useful for very small actors or customizable actors). Other than that, this is a great explanation!
@@mattlox3981 I consider that specific tutorials (such as horror game tutorials, rpg tutorials, survival tutorials) have no value... You only really learn with actual engine tutorials (learning about blueprints, references, interfaces and the different tools) Matt has some good tutorials but yeah Gorka... Meh... I've been on their Discord and reported the over use of casting (he used casting in components which beats the purpose of it)... And the answer I got from a mod was like "Oh yeah he knows he'll fix it in a later episode" And it hasn't been fixed yet lmao... One I do recommend is Ryan Lalley, he has really good tutorials on global engine systems
Subbed when I found this, wanted to say I wish the school I'm finishing a bachelors in game design would show this specifically but I'll make sure it becomes a signature that I showed someone this video when soft refs show up all over assignments.
Thank you so much for this explanation! I always hate when they just cast in tutorials and never explain what the drawbacks are and how to do it better because "it works for now".
I had just been thinking I know soft references are better for memory but didnt really know how to make use of them, and then this video popped up in my feed and answered all of my questions, great video as always 🎉
Im learning UE5 on tutorials and had no idea what soft references were. My project has a modular weapon system and when I checked my player size map... it was over 8 gigs. Now its at 250mbs. Thanks for the video!
The first 4 seconds are 10/10 xD I don't need tutorials, but I like to scroll through some of them to see 'what they teachin' over there' from time to time, and I see im not the only one pissed off by hundreds of tutorials that kinda make sense in isolated and limited tutorial environment, but demonstrate overall bad practices on a regular basis without mentioning it :D
I am a regular visitor here and I am subscribed to your channel as well :P One of the best unreal tutorial channels. Good content, calm and reasonable creator, no bs practices. Keep up the good work! :D
Interesting and well explained. I think part of the problem is that Unreal training often uses casting as a way to teach (maybe because it's quick and easy?) and so many people, depending on what they are trying to do, never learn or even know what's going on deeper under the hood and in many cases, can't even find a decent explanation anywhere! I have found errors in Unreal own docs and many tutorials are out of date and don't even work. So that's what's good about this video... it takes a deeper look with clear examples. I do feel like we are all struggling at some levels to figure Unreal out and so I'm mindful of what I hear and just factor that in, even with Unreal's own training materials.
For sure, Epic does show the faster and easier way at times to allow to focus on what point they want to drive home but not always. They have held shows on their UA-cam where they talk about this issue as well. But many don't have the time to look at streams for hours, and some might not realize all the valuable things they teach at times. So it is a bit of an unfortunate situation. They do not consistantly point out the pitfalls, and that might be why it slips by.
Thanks for the clear demo. This kind of ties in to the Reference Viewer, but another tradeoff to casting is when trying to migrate assets to different projects - you might end up migrating hundreds of assets when you just want one Blueprint (I guess this could be a plus since you'll know what assets you'll need, compared to using soft references)
Thanks for sharing. I’m a Level Designer currently trying to improve my Blueprint skills and I see so many scrappy tutorials out there that provide solutions to things that are feasible for only simple prototypes. Once it’s time to make a fully optimized game, that code becomes very inefficient.
You are very welcome. Yes, on small scale, many things are doable. But as part of a greater whole, many things need to be avoided or at least taken into consideration to not create massive technical debt.
Thank you. I sort of knew that casting is something to be careful, and not-to-be-overdone - but I never knew like the logic how to follow its consequences. Very useful video, thank you.
Good to know! learning so much of just connections and blueprints never realized the tax of soft vs hard referencing this has to be why some indie games even small ones run so bad because everything is stored in memory and not soft referenced. Very important info!
Just to add a bit to the conversation, casting in and of itself is not inheritly bad, it just depends on how you use it. If you have to cast, then its best to cast to the base class rather than some extended child class that contains a ton of art references or other references to weapons, etc. For example, if you need access to some base variable of a character, such as data about its movement component, you can just cast to the base character class and get the component reference from there to access what you need. Or if you need to check if an overlap detection was of a certain class, you could cast to the base class that you need. There are other ways of knowing some data, like using gameplay tags to identify types of enemies, or actors; but I wouldn't say casting is something to completely avoid. Perhaps in Blueprint only projects this is something to be more careful of, but if you are using a C++/BP hybrid, you have more flexibility of where you could hold data, and ensure you store crucial data inside of the base class rather than some extended child class. Interfaces and soft-references are always a good thing and should be a part of a developers suite of tools depending on the job they need to do, so kudos for sharing the knowledge, and awesome video/channel :)
Thank you! Of course there is always nuance to how and when to use certain approaches. That is true for almost all solutions, there are pros and cons to them all. I tried showing off the example with a lower base class example for the interface, using an actor instead of a heaver child class.
at timestamp @3:38 the OP shows the size map. But you can also see other things and how they are being "reference". For me I enjoyed the guided explanation, since Im relatively new to unreal(coming from Unity). While your(jevinscherries) explanation has some textual examples, seeing the visuals is a much better way for new people to grasp this subject. When I saw the output of the size map, I knew this was going to be an indispensable tool, especially in my niche of dev'ing- mobile development.
At 11:29 when you got rid of the class casting and used the conversion pin instead, you actually re-routed the wrong Exec pin (instead of the Completed one, the immediate one). Was that just a slip, or intentional? Asking because I was expecting the Spawn Actor node to give you a runtime error as it tries to immediately spawn the still-not-loaded helicopter, but for some reason it did not fail... 🤔 Maybe some caching mechanism from the previous Play run has helped loading the asset super-fast instead?!
It did not fail because the assets are already loaded in editor environment so it was able to just convert from soft to hard, and in a cooked game this would be an undefined behaviour - the crash might happen or not, depending on how fast the asset is gonna be loaded (but most certainly would crash)
Like @Zlevir said. You most likely want to hook your execution pin from completed to be assured that you asset is loaded in memory before you try to spawn it. The other pin is for code you may want to run in the meantime before it is fully loaded, if that is a need that you have.
This is very instructive, now I understand why in a previous project when the world loads in a server it was struggling and was taking a lot of memory. it was all because of the casting !! Thank you !
I really like this serie of "Be a better game dev", which shows through nice example how things work in UE. I had no idea about the map size, that's very interresting! A quick question tho: so we have cast and interface to make a reference (or to process some actions) to another instance. The last stuff that comes to my mind is the Event Dispatcher. What are the cost when you do the call / binding ? Is it like an interface (soft), or actually like a cast (hard)? Or even something else?
Glad to hear you like the series! You can not bind an event dispatcher to a class without having a reference of that specific type, because just like functions, events and variables the event dispat her is now known to exist unless it is of a reference of the specific type that has it.
binged through your blueprint tutorials last year, I was feeling like it needed some dusting after UE5 but look at this hard and soft refs debunked in 20 mins GGEZ! Thanks as always teach ^^
Hi since we're on the topic of references could you do a tutorial on when to use interface and event dispatcher to call event/function on different blueprint..i mostly use interface because i cant grasp the idea of when to bind and unbind event dispatcher. I find it easier just to implement interface on the blueprint i want to call on then just do interface call on the other bluerint.. however i just wondering if event dispatcher is less resource intensive or could be more useful than interface..thanks
I use dispatchers in many of my tutorials. Like this one for example: ua-cam.com/video/bdsROh8mQZk/v-deo.html It is a bit dependant on who knows of who, meaning who can reference whom. If you have two objects, A and B. Both have references to eachother, then you can just use direct communication, like interfaces. But if A knows of B, but B does not know of A. You can still have B communicate with A, because A can use a bind to an event in B. Also, if you have a large amount of objects that all know A and A knows all of them, you may want to just say in A that "thing X happened" with an event dispatcher and let everyone who is interested do their thing, instead of calling each object with an interface. But that is more a matter of preference. I will likely do so more tutorials on the topic in the future for sure.
@@LeafBranchGames thanks for the reply..i actually started unreal around the time when you were making the rpg series. Couldn't understand a thing back then but have no problem following the tutorial few months ago. Thank you so much for your hard work in educating everyone
Actually, if you just use the hard reference only it doesn't affect so much. It just increase the load times. It's not bad performance issue to start with, that's why Epic didn't emphasize this so much. It was an issue back then with hardware limitation but now with SSD and DDR5 ram it doesn't affect much.
Can you post a comparison load-time in a vid or pic? You may be right that load time isnt an issue (but I need to see). But still hard refs are bad when migrating assets. If I just want to migrate someone's character but not all heli textures etc.
@@kenalpha3That's because hard references are stored in an object variable. When migrating, the engine might miscalculate this. Regarding your question, I don't have any with me to show. I just learned it from experimenting and C++ knowledge. Also, you know when you put something in your level let it be static meshes/actors/Niagara/Sk mesh/ it always creates hard references. You can access them directly by drag and drop in the level blueprint if you don't believe me.
Yes and no. Hardware keeps improving but so does graphical fidelity. For example, before 4K textures were the high end of texture resolution, now we have 8K, and it will likely continue. Since this arms race between hardware imporving and developers trying to get more out of their graphics, having to load in larger and larger amounts of data in memory will be significant.
its not just load times, its in-game memory usage. If you hard reference too much you can easily reach some ridiculously high numbers that will mean you run out of memory which means the game has to constantly shuffle stuff between SSD and memory and even on a high speed SSD that will cause massive stutters.
One thing I don't understand is - when you have a hard reference in a bp class, does it mean that every spawned object of that bp will create it's own copy of a hard referenced object? For example My_BP is 1 mb, and My_Referenced_BP is 100 mb. I spawn 10 My_BP actors, does it mean that memory consumption by references will be 10*100 = 1000 mb? Or will it be just 100 mb?
I would like to see some real game worl example. For example in the level you need to have a lot of object, but most of them are conditional, player need to do something special before they appear there. How to this? You can put there blueprint wihh the logic, but without mesh itself and mesh itself can be loaded only when needed right? But I need to see that mesh in the editor to be able to position it correctly. How to that?
The usage would vary very much from game to game because they have different needs and different behaviors. But I can make a note of showing something larger in a future tutorial that should hopefully be more in depth.
Would you say that casting to something thats already loaded into memory isnt a huge deal then? Like if triggers, or actors that are already visible in the level cast to the player character? If the player is already loaded because youre playing the game, then casting to it should be fast and have minimal overhead. Or is there something else to be careful of in these situations?
No, you are correct. If something already is in memory, or something that is very likely to be in memery anyway - like the main weapon of a character, then the hard reference won't cause any larger of a memory footprint, so then having the reference will make it easier to work with. In that case, it is not an issue to reference it.
Like others, it was the thumbnail about Gorka and Aspland that made me watch this. I've just started seriously sitting down after having watched or gone through a couple full tutorial series (like Ryan Laley's) to get a basic understand of BP and all I've been doing is very simple, (movement, damage interaction, hit reaction, dodge), and, so far, I've avoided bloating my memory drain, but this video showed me something that I hadn't even known about. So, thank you. I actually was worried about optimizing memory long term, but if I can take care of it while doing stuff that's much better. I do have a question, though. My character is using a mixamo rig w/mixamo animations, not the built in one, but the BP is a child of the default one. Default is calling references to manny and quinn. I don't know how heavy those are, but is there a way to remove them without breaking things? I used the default so I could put common actions since I intend to have at least one more playable character with some different actions, but neither is using the default rig so I don't know if I need to keep those.
It depends a bit. If you are for exanple only going to use Mixamo characters and animations, you could just create your own blueprint inheriting the character class and create and setup an animation blueprint. Or you could achieve the same by just not making use of the manny animation blueprints and and meshes but use your own assets. So you can for sure get rid of them, but if you are retargeting animations and want to make an easy way of using multiple different rigs, then you can benefit from the existing setup for convenience.
That intro tho xD haha Good one lol... Great video as always. Mate I have a question for you or maybe a tut request >.>. You seem like a smart guy that can give me some insights. I am making a FPP mele game using swords etc. I searched and can't seem to find any info or guidance about recoil of mele weapons. So for example you hit a wall and the weapon bounces back, or maybe hit an enemy with a hammer and the animation stops and recoils back to idle and not going thru the enemies. Or even when the enemy blocks or swing. Stay awesome! Cheers!
Thank you! There are probably a few different approaches you can go about this. One way is physical animations. If you want to delve into that aspect, then the youtube channel prismaticadev has some informative tutorials around that. Alternatives that I can think of immediately would be upon identifying a hit result, you could use something akin to a hit stop like effect for the animation, essentially pausing it, and then refersing it a few frames before blending back to the normal animation state. I think either of these should give a decent result.
@@LeafBranchGames Yeah I figured. Checked the Prismaticadev physic anim video a while ago. Tbh looks way complex and hard to tweak. The animation hit stop effect sounds more easy >.>. What do you mean by refreshing it for few frames before blending back?
@@LeafBranchGames Oh reversing XD... that was my initial idea I tried , however I was unable to find a way to pick a starting position to play the animation in reverse from.. I was not able to figure a way to get the exact frame position the animation was in when the "collision" happened and to play it from reverese from that point in the animation. Hope this makes sense >.>
@@borisaceski6401 You could try and see if you can alter the current montage playing and let it be at the position it is in, and adjust the play rate to -1 to reverse.
thx, get to the point and well explained , i think make an parent abstract helicopter class and only expose nessassary function, child helicopter class can refer to heavy memory resource third person only get hard reference to abstract helicopter it possible can do similar as soft reference, and get type safe compare to interface. i didn't check yet, I will check it when i work on my game, apology if i'm wrong.
The concept is correct. You can have a light weight placeholder that you load in as the need arises/or by having children with more complexity and by doing so, you could have hard references that are still not very demanding memory wise.
A lot of of tutorials fail to show best practices. If you were to do some of the stuff you see in these tutorials in a professional setting, you'd generate so much tech debt, and spend more time refactoring than you would developing.
I've seen some awful tutorials. They all start with "just open the Third Person template", then it's Blueprint spaghetti with an empty Details tab covering half the screen. They never use C++ either. Some of them even fire up UE5 and then use the old Input System. That's criminal. Other things like "Get all objects of class" every time rather than using a data structure and storing these things once. Perhaps Blueprint has been well optimised by Epic and that's not a problem, but it smells bad. It's certainly a disaster in Unity and leads to a noticeable performance drop. What you get is a very basic and poor implementation of the "what", without explaining the "why". Things like wanting to use Event Dispatchers, but having a hard reference to the source of the event. That's pointless, it doesn't scale and it breaks the Observer pattern.
These are the legends UA-cam often misses to push out You my sir are a legend for these videos! Would really love to have more of these tutorials considering the way of explanation is just so good!❤ Keep up the good work!❤️🔥
Thank you, appreciate that! There are a total of three episodes on the series so far and a fourth on the way soon. So hopefully those are useful to you as well!
Learned a lot from this video, thanks a million for the gr8 content! Quick question,,, What's the best way to retrieve information from the character BP? I'm using hard reference to check the state of a Boolean but I see now it's not as efficient as I thought.
As I said earlier, this is a war 😅. You're tutorials is very useful and helping to understand better basics of unreal engine. No one explains it correct as like You!
One question Guy... 13:27 time.. Do you consider the bad use "Get Actor of Class" or you´ve used these one in this case to understand the main reason that is the right use of soft/hard references only???. Thanks you anyway.. Because Iam very worried and I have terrible questions when I invoque "get actor of class"... Only this thing. Very nice content, Congratulations!!!.
Get actor of class is bad in the sense that it will need to go through all the actors to find the matching ones of your query. So as you have larger worlds with more actors, this will be slower. So it is mainly something you don/t want to see happening often, like in loops in ticks and such. But if you have it as a "one off", like there is a very specific actor (or actors) you need to gather and you do it once in a begin play in an object or something to gather the references - then it will not happen often and is not likely to be a problem.
So basically, if I can associate this with C++ class instantiation, making hard references is akin to calling multiple new calls (or however you create your objects), which means that every time you make your original class, the memory usage of the class will be created, along with every other class you create in the constructor or wherever at initialization time. Whereas a soft reference, is akin to creating objects ONLY when needed.
so @11:51 you are skipping the async load altogether since you are not using the completed pin anymore or even the output of the load, so what the point of even doing it?
And the worst part, you are wiring your brain with a wrong methodology using castings, karma will back in a dark coat. " I have seen things you people wouldn't believe...casts on tick events, casts on collision boxes without use it...3 casts inside anim class...."
Really well explained, however i still have one question about soft references, lets say that I have a weapon system that uses soft references from a data asset for its stats, animations etc. when I swap weapons to a different one, since soft references become hard once loaded, does that mean that all the data from my previous weapon remains loaded? how does this affect memory and how should I organize a system with lots of equipable weapons and tools that each have their own logic and animations? thank you for your videos
I've been doing a fair amount of interfaces instead of casting, but one thing I do is have my enemy cast to my player to store a reference to him on begin play. Is there a better way to do that?
Thanks man, I figured out the general use, but this async load is new to me. As i understand it, an async loading would produce less hitches when loading into memory more complex stuff, as it's a lower priority load in comparison to standard spawning. Or am i wrong?
Well, sort of. Instead of using the game thread to load in an object, which would cause the game to halt until that is done, it is done in a different thread, so technically a parallell process.
Thank you! I am realizing more and more that most tutorials don't give you the tools to manage your game well. Do you have a video on player states(or states in general)? Like managing IsSprinting, IsFalling, IsLandingIntoSliding, etc. I am making a system with enumeration. It seems like a good way. Better than boolean spaghetti..?
Not spcifically, not yet. You may want to look into my tutorial on gameplay tags: ua-cam.com/video/edJGE0aidZY/v-deo.html and even if you are not making an RPG, my free RPG course teaches you a bunch of useful things: ua-cam.com/play/PLNBX4kIrA68lz8GSxTQKX_0B23tHP6Bl9.html
What about if i use C++ only and the reference viewer is entirely hard references... (i use just simple * pointers in c++) now i should convert some of the parts into soft references in c++? Another question, maybe you would know since i can't truly find answer on this, do i have to clear DECLARE_MULTICAST_DELEGATE() macro delegates on object destruction which have delegate? for example i use static delegate in enemy class when enemy dies it broadcasts to certain functions like WaveManager update UI: DECLARE_MULTICAST_DELEGATE(FOnEnemyDeath); static inline FOnEnemyDeath OnEnemyDeath; AEnemy::OnEnemyDeath.AddUObject(instance, &UWaveManager::updateEnemiesAmount); and clear like this: void AEnemy::EndPlay(const EEndPlayReason::Type EndPlayReason) { Super::EndPlay(EndPlayReason); OnEnemyDeath.RemoveAll(this); }
Is there a way to "Unload" the Async Loaded Asset when no longer needed in memory and then be able to soft reference it and load again? I see that when it is once Async Loaded it will become forever the hard reference for the Player on the moment it is fully loaded from the soft to hard reference, even when later actor is no longer needed it stays loaded in memory
If we want to trigger something in some specific objects in the map with interfaces, should we use get all actors of that class and pass them as targets? Doest that use memory as well?
Preferably, you should not send messages to all actors if it is only relevant for one or a subset of actors. Getting all actors of a class, will create hard references as well.
In the first five minutes you described hard and soft references 100x better and more to the point than it took Epic's own rambling, idiotic "Demystifying Soft Object References" video. Earned yourself a subscriber.
In which cases should I use soft references and when not or can I use soft references for each casting (of characters like enemy npcs (or in they cases for the player)) or variable (like animation montage as example)?
Ive watched this 3 times but I'm still confused and have so many questions It almost feels like what Ive learned about ue5 was a lie for the past 2 years What do I do if I want to call a event in another blueprint? Or a function? Ive tried using interfaces but I can never get it to work sometimes. Why spawn an actor when its already in the level? Like when I turn a valve and the water sprinker (which is a different blueprint) to activate a particle? I just got my game design major and there is still so much to learn about ue5
Calling an interface is essentially teh same as calling an event or function in a different blueprint. It is just a bit decoupled. When you create something, let us say you make a game where you sneak your way to some objective. Then you have guards walking around. It makes no sense to spawn them, because you want to, in design time - in the editor, see the amount of guards and where tehy are. Something that you cant't grasp if all of your guards spawn at the start of the mission. But if you have something like a zombie game where at some point hordes of zombies will appear to assault the base, it makes little sense to have them all in the level taking up performance until the point they are supposed to attack. Then it makes more sense to just have a place where you spawn these zombies in. Learning is a journey, it never ends.
if something exist on the map and you have a hard reference does it store it self twice in memory ? an analisis on how the system works as total based on this question would be really useful ^^ For example if the helicopter was already in the world before our character spawned or if two things have a hard ref to something does it mean its loaded twice ?
First of all, many thanks for sharing your knowledge in general and in particular this video, because it's a must-watch. The icing on the cake would have been to include an example of a soft object reference in addition to the soft class reference, other than that, nice job! I think I'll be taking this video from the opposite point of view of most people watching it because I've been trying to avoid casting like oil and water. Still, this video has proved to me that you don't need to do always the workaround if something is already in memory. There is one thing that bothers me and I would like to ask you what approach would you follow about it. Let's say you have object A and object B. Object A has some dispatchers and object B wants to bind/subscribe to them but they don't know anything about each other. How would you bind object B to object A's dispatchers without having to cast A within object B? Do you need a third party that knows about them both? Do you create an Interface for object A that just returns itself whenever it is used? How? Any tips on the subject would be much appreciated.
Glad to hear you like it, and that is the correct understanding. If you don't know what will be in memory you should avoid casting to make sure you don't load unecessary things. But if you know what will be in memory, then you can of course work around that. Regarding dispatchers, it depends on the event you are trying to subscribe to. If it for example is a onDestroy event, then that is something that exist on the actor level, so you only need an actor type reference. If it is a specific event that only exist on a specific class, then there is no way around it, you need to cast to know the type to know the event is there to setup listening to.
@@LeafBranchGames Great Video!what i have some trouble understanding is: let's say we always have an object A loaded in the map and its size is 20MB, if other 2 actors cast to it, will memory footprint increase linearly for each (so +40MB) or it won't because that actor A was already loaded in the map from the beginning?
So in short using interfaces instead of direct casting is a good practice right sir? and always try to use soft reference while development got it. Thanks a lot keep more of these videos coming it helps a lot and now im going to remove cast and implement interface where necessary
Interfaces are great for sure. But not all hard references are bad. If you have a character that always have a specific sword, is never without it, then it would always be loaded in memory regardless. So a hard reference there may not be bad. So there are some circumstances that are not as black or white. But as a rule of thumb, it is a good start!
@@LeafBranchGames yeah again thanks a lot for make it easier for everyone keep more of these videos coming. Who knows what other deal breaking mistakes I have made in my game 😂😂😂
Video was useful although at 0:38 you say you will talk about components and then later in the video you say you won't cover them in this video which is a tad frustrating!
I get that. Sorry! Didn't mean to imply I would get into depths about components, but I can totally understand the misgiving. I may expand on it further in another video to compensate.
@@LeafBranchGames that would be great! Re-reading my comment I should mention that the information given in the video was great and distils the benefits of soft references very efficiently. The video definitely is a good reference even if it didn't cover the entirety of what I was expecting from the intro!
Throwing some shade with that thumbnail? lol It's also worth mentioning that casting to a C++ class from a blueprint is free from a memory standpoint. So say that you have your character largely defined in your C++ class for example, casting to it from Actor/Pawn whatever in a blueprint does not increase the memory footprint of the blueprint where the cast is performed.
Is that true? That feels like it should not be the case from an objective stand point. I will have to check that out. Thanks for sharing regardless! Shade where shade is due!
First of all, thanks for this really nice and needed resource. I would love to ask you something. When you show the size map, the default option shown is the Disk Size, but you keep reffering as the space in memory. Should we change the tab from disk size to Memory size (or whatever name it is, sorry, I am not in UE right now) to really see what is going on? Or with Disk Size is more than ok? Again, many many thanks.
Both disc size and memory size will both increase with references. If you are looking to really min max how much is used by your RAM, then the memory size is what you want to look at as a measure. If you are just looking to reduce dependancies of assets, then either view is ok to look at because you are just looking to decrease references as much as you can, maybe not shooting for a specific target value.
Thanks for the video, it's really cool. Though, any suggestions on actual player blueprint size, for example? I mean, let's say I have an ULTRAKILL-sized game (in terms of mechanics and code complexity). Is there any recommended player blueprint size for a game like that? Right now, in my prototype, the player blueprint weighs ~150MB (of which most of it is taken up by the UI), and I don't know if that's a good or bad result. P.s. I use hard references in some places, and soft references in other places, according to the situation.
Not really. It depends on the situation and what you are trying to accomplish. A really light weight game has the benefit of being able to be loaded very quickly. A game with a lot of dependencies will take a long while to load but on the other hand you have those assets available for quick use now. It also sets the minimum requirement of your player base.
I remember I was trying to do the invoker from dota into unreal engine... and omg I was like why is my game soooo laggy.. I'm pretty sure all the balls like in invoker I made them have a hard reference to the player and also reference to the meshes for the skills hahahha and you multiply that by 3 and it get worse. I think lately I'm trying to have most of the logic into the player controller because I can used the "get pawn controlled" also for things like in the widgets I use those functions. I didn't know about the "cast to..." also count as a hard ref so that's good to know thanks :D. Another thing I do is that because using interfaces it gets a bit messy and then you don't know if you are adding the correct function to the interface, what I do is making all custom events first and when I get all clean and looks nice I have a better picture to then created the blueprint interfaces and then I just update the custom event calls, a bit long work but the thing is that you work faster in the first part Edit: damn... so I just realized if you have different cast to different blueprints... that means you're basically adding hard references for all those blueprints?
That is indeed what could happen. You can have a cascading effect of hard references causing all of the assets to be loaded despite not even using them at all. Doing custom events and then replacing with interfacing is fine. We don't always know how things will turn out code wise, so refactoring the code is a good thing.
So just so im 100% clear, on the reference viewer: If an object is on the right hand side of the viewed object (downstream), it will get loaded by the currently viewed object But if its on the left hand side of the currently viewed object (upstream) it won't get loaded by the currently viewed object?
If I have 2 assets with hard references to a third asset, will that third asset still only be loaded once? Also, if I have a small one-room game (ie something quick for a game jam) and almost every asset has been placed in the room from the start, is there a benefit to not using hard refs outside of trying to use best practice?
lmao i just realized the shade to "gorka games" and "matt aspland" in the thumbnail im dying lmaooooooooooo
:)
In fact, Gorka and Matt are good for beginners. You won't teach string theory in first grade, but will start with simple mathematics?
@@TheModExperiment In fact, they are not.
@@LeafBranchGames So what are you thinking about Ryan Laley?🎩🎩🎩
@@TheModExperiment Why do you ask?
This video is great.
When starting I never understood casting because all the tutorials were so simple and manually targeted. You know the ones, connect door to trigger by directly referencing it from the map (this is not scalable) rather than building a door + trigger that can be retargeted etc. Because of this I learnt interfaces and event dispatchers before I understood how to use casting. Turns out this was a pretty good move. You explain things very well.
Thank you! Yes, I know exactly what you mean. :)
Dissing two channels with a picture: Done
Should be an achiement unlock for it or something, right?
As someone getting into this as a hobby these in depth best practice videos are gold. Thank you
Glad to be of help!
So, having a variable referencing a actor or casting to it directly in the blueprint consumes more memory but is faster, while soft referencing that same object consumes less memory but takes some time to access it.
After all this time, I finally learned how to use soft references, thank you.
Glad to hear it!
I can't imagine a time when I'd want to load something slowly in a game that isn't turn based.
@@UA-camAccountManmaybe for character or weapons skins? You may have hundreds in a game and so they are loaded from a soft reference. There may be a fuzzy transition texture to show the skin is updating if it takes a second to load?
This is a misleading understanding of the problem.
If you cast to another class, it is ALWAYS loaded when any instance of your own class is.
Say you cast to "OpenWorldLevel" to get the time of day, as an example. And you do this from a "timer" widget that just displays a clock.
If you ever load that timer widget, it must first load OpenWorldLevel, and every asset that OpenWorldLevel depends on, before the timer can be loaded.
Your 3Kb timer becomes a 500MB or even several GB asset. This is a very extreme case, indicating what happens when you've got dependancy chains everywhere. But it is exactly what you end up with when following a typical UA-cam tutorial: Every class casts to every other. And so, to load anything, you have to load everything. And you end up wondering why you're eating 18GB of RAM in an empty level when you try refactoring later.
Right click an asset in the content browser, and select "Size Map." At the top right, select the Memory option (not disk size.) This will explain a lot in a few seconds.
So months later I come back to this because I actually wanna try out soft references and I just now realized what you did in the thumbnail, hilarious
Repeat value!
There is a mistake @11:51. This will cause an error or crash in a packaged game (or on a restart of the editor). It only works in your example because the editor has it loaded in memory due to GC not having been run yet. If you use Async you MUST use completed to ensure no errors.
If you Load Asset Blocking you can avoid and async call and just delay in the frame (useful for very small actors or customizable actors).
Other than that, this is a great explanation!
Yes, that is correct. Thank you for sharing!
I watched a couple of videos about this before and never really understood how this can be beneficial until now. Thank you!
My pleasure!
It's a lecture that you can't even listen to in paid lectures!
Tutorial Thank you for the high quality tutorial :)
Thank you, appreciate it!
That thumbnail instantly triggered me, but it's true! Good video 👍
Thank you!
i really don't like talking bad about other UE channels but those gorka "tutorials"... lol
@@mattlox3981 I consider that specific tutorials (such as horror game tutorials, rpg tutorials, survival tutorials) have no value... You only really learn with actual engine tutorials (learning about blueprints, references, interfaces and the different tools)
Matt has some good tutorials but yeah Gorka... Meh... I've been on their Discord and reported the over use of casting (he used casting in components which beats the purpose of it)... And the answer I got from a mod was like "Oh yeah he knows he'll fix it in a later episode"
And it hasn't been fixed yet lmao...
One I do recommend is Ryan Lalley, he has really good tutorials on global engine systems
Subbed when I found this, wanted to say I wish the school I'm finishing a bachelors in game design would show this specifically but I'll make sure it becomes a signature that I showed someone this video when soft refs show up all over assignments.
High praise. Thank you! Please do share among your learning peers. :)
Thank you so much for this explanation! I always hate when they just cast in tutorials and never explain what the drawbacks are and how to do it better because "it works for now".
Happy to hear it is appreciated, and I fully agree with you. :)
I had just been thinking I know soft references are better for memory but didnt really know how to make use of them, and then this video popped up in my feed and answered all of my questions, great video as always 🎉
I nsensed a disturbance in the force and knew this would be an issue you would be running into. I am glad I was able to make it in time!
big thanks, now i understand more why we should cast as least as possible
Glad to hear it!
Im learning UE5 on tutorials and had no idea what soft references were. My project has a modular weapon system and when I checked my player size map... it was over 8 gigs. Now its at 250mbs. Thanks for the video!
Glad to hear it was useful!
The first 4 seconds are 10/10 xD I don't need tutorials, but I like to scroll through some of them to see 'what they teachin' over there' from time to time, and I see im not the only one pissed off by hundreds of tutorials that kinda make sense in isolated and limited tutorial environment, but demonstrate overall bad practices on a regular basis without mentioning it :D
Well then, thank you for the visit. :)
I am a regular visitor here and I am subscribed to your channel as well :P One of the best unreal tutorial channels. Good content, calm and reasonable creator, no bs practices. Keep up the good work! :D
@@Zlevir Thank you very much! I very much appreciate that!
Interesting and well explained. I think part of the problem is that Unreal training often uses casting as a way to teach (maybe because it's quick and easy?) and so many people, depending on what they are trying to do, never learn or even know what's going on deeper under the hood and in many cases, can't even find a decent explanation anywhere! I have found errors in Unreal own docs and many tutorials are out of date and don't even work. So that's what's good about this video... it takes a deeper look with clear examples. I do feel like we are all struggling at some levels to figure Unreal out and so I'm mindful of what I hear and just factor that in, even with Unreal's own training materials.
For sure, Epic does show the faster and easier way at times to allow to focus on what point they want to drive home but not always. They have held shows on their UA-cam where they talk about this issue as well. But many don't have the time to look at streams for hours, and some might not realize all the valuable things they teach at times. So it is a bit of an unfortunate situation. They do not consistantly point out the pitfalls, and that might be why it slips by.
DAMN what was the music in the beginning??! The melody was so good
I think so too! It is called "Borderless" by Aakash Gandhi.
Thanks for the clear demo. This kind of ties in to the Reference Viewer, but another tradeoff to casting is when trying to migrate assets to different projects - you might end up migrating hundreds of assets when you just want one Blueprint (I guess this could be a plus since you'll know what assets you'll need, compared to using soft references)
Thanks for sharing. I’m a Level Designer currently trying to improve my Blueprint skills and I see so many scrappy tutorials out there that provide solutions to things that are feasible for only simple prototypes. Once it’s time to make a fully optimized game, that code becomes very inefficient.
You are very welcome. Yes, on small scale, many things are doable. But as part of a greater whole, many things need to be avoided or at least taken into consideration to not create massive technical debt.
Thank you. I sort of knew that casting is something to be careful, and not-to-be-overdone - but I never knew like the logic how to follow its consequences. Very useful video, thank you.
Glad to hear it was informative. :)
that is amazing ,I learned a lot, you are my kamisama das.
Thank you, super happy to hear that. :)
Good to know! learning so much of just connections and blueprints never realized the tax of soft vs hard referencing this has to be why some indie games even small ones run so bad because everything is stored in memory and not soft referenced. Very important info!
Glad to hear you like it!
Just to add a bit to the conversation, casting in and of itself is not inheritly bad, it just depends on how you use it. If you have to cast, then its best to cast to the base class rather than some extended child class that contains a ton of art references or other references to weapons, etc. For example, if you need access to some base variable of a character, such as data about its movement component, you can just cast to the base character class and get the component reference from there to access what you need. Or if you need to check if an overlap detection was of a certain class, you could cast to the base class that you need.
There are other ways of knowing some data, like using gameplay tags to identify types of enemies, or actors; but I wouldn't say casting is something to completely avoid. Perhaps in Blueprint only projects this is something to be more careful of, but if you are using a C++/BP hybrid, you have more flexibility of where you could hold data, and ensure you store crucial data inside of the base class rather than some extended child class.
Interfaces and soft-references are always a good thing and should be a part of a developers suite of tools depending on the job they need to do, so kudos for sharing the knowledge, and awesome video/channel :)
Thank you! Of course there is always nuance to how and when to use certain approaches. That is true for almost all solutions, there are pros and cons to them all. I tried showing off the example with a lower base class example for the interface, using an actor instead of a heaver child class.
at timestamp @3:38 the OP shows the size map. But you can also see other things and how they are being "reference". For me I enjoyed the guided explanation, since Im relatively new to unreal(coming from Unity). While your(jevinscherries) explanation has some textual examples, seeing the visuals is a much better way for new people to grasp this subject. When I saw the output of the size map, I knew this was going to be an indispensable tool, especially in my niche of dev'ing- mobile development.
You're talking about polymorphism and virtual methods... One of the most powerful tools in C++ ❤
Great concepts, thank you sir. Subbing and attentive to all best practices you post for us 🎉
Thank you for the support. :)
At 11:29 when you got rid of the class casting and used the conversion pin instead, you actually re-routed the wrong Exec pin (instead of the Completed one, the immediate one). Was that just a slip, or intentional? Asking because I was expecting the Spawn Actor node to give you a runtime error as it tries to immediately spawn the still-not-loaded helicopter, but for some reason it did not fail... 🤔 Maybe some caching mechanism from the previous Play run has helped loading the asset super-fast instead?!
It did not fail because the assets are already loaded in editor environment so it was able to just convert from soft to hard, and in a cooked game this would be an undefined behaviour - the crash might happen or not, depending on how fast the asset is gonna be loaded (but most certainly would crash)
Like @Zlevir said. You most likely want to hook your execution pin from completed to be assured that you asset is loaded in memory before you try to spawn it. The other pin is for code you may want to run in the meantime before it is fully loaded, if that is a need that you have.
@@LeafBranchGames - It would be to good amend the video with this correction because it will lead to confusion for people just learning the topic.
This is very instructive, now I understand why in a previous project when the world loads in a server it was struggling and was taking a lot of memory. it was all because of the casting !! Thank you !
Indeed!
I really like this serie of "Be a better game dev", which shows through nice example how things work in UE. I had no idea about the map size, that's very interresting! A quick question tho: so we have cast and interface to make a reference (or to process some actions) to another instance. The last stuff that comes to my mind is the Event Dispatcher. What are the cost when you do the call / binding ? Is it like an interface (soft), or actually like a cast (hard)? Or even something else?
Glad to hear you like the series!
You can not bind an event dispatcher to a class without having a reference of that specific type, because just like functions, events and variables the event dispat her is now known to exist unless it is of a reference of the specific type that has it.
@@LeafBranchGames Oh yes, now that I think about it, you're right!
binged through your blueprint tutorials last year, I was feeling like it needed some dusting after UE5 but look at this hard and soft refs debunked in 20 mins GGEZ! Thanks as always teach ^^
Thank you. :)
Be a better game dev Is the serious devs need. Thank you so much
My pleasure!
I've been learning unreal for over 2 years now and I didn't know a lot of this, great job on this video.
Thank you!
Very well explained! Great video as usual.
Thank you!
Hi since we're on the topic of references could you do a tutorial on when to use interface and event dispatcher to call event/function on different blueprint..i mostly use interface because i cant grasp the idea of when to bind and unbind event dispatcher. I find it easier just to implement interface on the blueprint i want to call on then just do interface call on the other bluerint.. however i just wondering if event dispatcher is less resource intensive or could be more useful than interface..thanks
I use dispatchers in many of my tutorials. Like this one for example: ua-cam.com/video/bdsROh8mQZk/v-deo.html
It is a bit dependant on who knows of who, meaning who can reference whom.
If you have two objects, A and B. Both have references to eachother, then you can just use direct communication, like interfaces.
But if A knows of B, but B does not know of A. You can still have B communicate with A, because A can use a bind to an event in B.
Also, if you have a large amount of objects that all know A and A knows all of them, you may want to just say in A that "thing X happened" with an event dispatcher and let everyone who is interested do their thing, instead of calling each object with an interface. But that is more a matter of preference.
I will likely do so more tutorials on the topic in the future for sure.
@@LeafBranchGames thanks for the reply..i actually started unreal around the time when you were making the rpg series. Couldn't understand a thing back then but have no problem following the tutorial few months ago. Thank you so much for your hard work in educating everyone
@@zzzmobilelegend9871 Thank you, glad to hear of your learning progress. :)
Actually, if you just use the hard reference only it doesn't affect so much. It just increase the load times. It's not bad performance issue to start with, that's why Epic didn't emphasize this so much. It was an issue back then with hardware limitation but now with SSD and DDR5 ram it doesn't affect much.
Can you post a comparison load-time in a vid or pic?
You may be right that load time isnt an issue (but I need to see). But still hard refs are bad when migrating assets. If I just want to migrate someone's character but not all heli textures etc.
@@kenalpha3That's because hard references are stored in an object variable. When migrating, the engine might miscalculate this.
Regarding your question, I don't have any with me to show. I just learned it from experimenting and C++ knowledge. Also, you know when you put something in your level let it be static meshes/actors/Niagara/Sk mesh/ it always creates hard references. You can access them directly by drag and drop in the level blueprint if you don't believe me.
@@kenalpha3 You can learn more by researching about memory leak in c++ they have handlers for this
Yes and no.
Hardware keeps improving but so does graphical fidelity. For example, before 4K textures were the high end of texture resolution, now we have 8K, and it will likely continue.
Since this arms race between hardware imporving and developers trying to get more out of their graphics, having to load in larger and larger amounts of data in memory will be significant.
its not just load times, its in-game memory usage. If you hard reference too much you can easily reach some ridiculously high numbers that will mean you run out of memory which means the game has to constantly shuffle stuff between SSD and memory and even on a high speed SSD that will cause massive stutters.
One thing I don't understand is - when you have a hard reference in a bp class, does it mean that every spawned object of that bp will create it's own copy of a hard referenced object?
For example My_BP is 1 mb, and My_Referenced_BP is 100 mb. I spawn 10 My_BP actors, does it mean that memory consumption by references will be 10*100 = 1000 mb? Or will it be just 100 mb?
really good explanation! thank you! (I laughed so hard from 00:00 to 00:04 , I understood the reference xD )
❤
Just came here from a Gorka tutorial where he was setting a bool to false if it's already false. Good channel, this one.
Simply fantastic!
can you send a link to that one or tell me the name I want to see that
I would like to see some real game worl example. For example in the level you need to have a lot of object, but most of them are conditional, player need to do something special before they appear there. How to this? You can put there blueprint wihh the logic, but without mesh itself and mesh itself can be loaded only when needed right? But I need to see that mesh in the editor to be able to position it correctly. How to that?
The usage would vary very much from game to game because they have different needs and different behaviors. But I can make a note of showing something larger in a future tutorial that should hopefully be more in depth.
Bit of a spicy thumbnail there
Credit where credit is due.
Would you say that casting to something thats already loaded into memory isnt a huge deal then? Like if triggers, or actors that are already visible in the level cast to the player character? If the player is already loaded because youre playing the game, then casting to it should be fast and have minimal overhead. Or is there something else to be careful of in these situations?
No, you are correct. If something already is in memory, or something that is very likely to be in memery anyway - like the main weapon of a character, then the hard reference won't cause any larger of a memory footprint, so then having the reference will make it easier to work with. In that case, it is not an issue to reference it.
Thank you for the detailed explanation!
My pleasure!
Like others, it was the thumbnail about Gorka and Aspland that made me watch this. I've just started seriously sitting down after having watched or gone through a couple full tutorial series (like Ryan Laley's) to get a basic understand of BP and all I've been doing is very simple, (movement, damage interaction, hit reaction, dodge), and, so far, I've avoided bloating my memory drain, but this video showed me something that I hadn't even known about. So, thank you. I actually was worried about optimizing memory long term, but if I can take care of it while doing stuff that's much better.
I do have a question, though. My character is using a mixamo rig w/mixamo animations, not the built in one, but the BP is a child of the default one. Default is calling references to manny and quinn. I don't know how heavy those are, but is there a way to remove them without breaking things? I used the default so I could put common actions since I intend to have at least one more playable character with some different actions, but neither is using the default rig so I don't know if I need to keep those.
It depends a bit. If you are for exanple only going to use Mixamo characters and animations, you could just create your own blueprint inheriting the character class and create and setup an animation blueprint. Or you could achieve the same by just not making use of the manny animation blueprints and and meshes but use your own assets. So you can for sure get rid of them, but if you are retargeting animations and want to make an easy way of using multiple different rigs, then you can benefit from the existing setup for convenience.
That intro tho xD haha Good one lol... Great video as always. Mate I have a question for you or maybe a tut request >.>. You seem like a smart guy that can give me some insights. I am making a FPP mele game using swords etc. I searched and can't seem to find any info or guidance about recoil of mele weapons. So for example you hit a wall and the weapon bounces back, or maybe hit an enemy with a hammer and the animation stops and recoils back to idle and not going thru the enemies. Or even when the enemy blocks or swing. Stay awesome! Cheers!
Thank you! There are probably a few different approaches you can go about this. One way is physical animations. If you want to delve into that aspect, then the youtube channel prismaticadev has some informative tutorials around that. Alternatives that I can think of immediately would be upon identifying a hit result, you could use something akin to a hit stop like effect for the animation, essentially pausing it, and then refersing it a few frames before blending back to the normal animation state. I think either of these should give a decent result.
@@LeafBranchGames Yeah I figured. Checked the Prismaticadev physic anim video a while ago. Tbh looks way complex and hard to tweak. The animation hit stop effect sounds more easy >.>. What do you mean by refreshing it for few frames before blending back?
@@borisaceski6401 Sorry, typo, meant "reversing" it for a few frames, sort of like a recoil.
@@LeafBranchGames Oh reversing XD... that was my initial idea I tried , however I was unable to find a way to pick a starting position to play the animation in reverse from.. I was not able to figure a way to get the exact frame position the animation was in when the "collision" happened and to play it from reverese from that point in the animation. Hope this makes sense >.>
@@borisaceski6401 You could try and see if you can alter the current montage playing and let it be at the position it is in, and adjust the play rate to -1 to reverse.
thx, get to the point and well explained ,
i think make an parent abstract helicopter class and only expose nessassary function,
child helicopter class can refer to heavy memory resource
third person only get hard reference to abstract helicopter
it possible can do similar as soft reference, and get type safe compare to interface.
i didn't check yet, I will check it when i work on my game, apology if i'm wrong.
The concept is correct. You can have a light weight placeholder that you load in as the need arises/or by having children with more complexity and by doing so, you could have hard references that are still not very demanding memory wise.
A lot of of tutorials fail to show best practices. If you were to do some of the stuff you see in these tutorials in a professional setting, you'd generate so much tech debt, and spend more time refactoring than you would developing.
So true. The technical debt would be immense.
I've seen some awful tutorials.
They all start with "just open the Third Person template", then it's Blueprint spaghetti with an empty Details tab covering half the screen. They never use C++ either.
Some of them even fire up UE5 and then use the old Input System. That's criminal.
Other things like "Get all objects of class" every time rather than using a data structure and storing these things once. Perhaps Blueprint has been well optimised by Epic and that's not a problem, but it smells bad. It's certainly a disaster in Unity and leads to a noticeable performance drop.
What you get is a very basic and poor implementation of the "what", without explaining the "why". Things like wanting to use Event Dispatchers, but having a hard reference to the source of the event. That's pointless, it doesn't scale and it breaks the Observer pattern.
These are the legends UA-cam often misses to push out
You my sir are a legend for these videos!
Would really love to have more of these tutorials considering the way of explanation is just so good!❤
Keep up the good work!❤️🔥
Thank you, appreciate that!
There are a total of three episodes on the series so far and a fourth on the way soon. So hopefully those are useful to you as well!
Learned a lot from this video, thanks a million for the gr8 content!
Quick question,,, What's the best way to retrieve information from the character BP? I'm using hard reference to check the state of a Boolean but I see now it's not as efficient as I thought.
As I said earlier, this is a war 😅. You're tutorials is very useful and helping to understand better basics of unreal engine. No one explains it correct as like You!
Thank you, appreciate that!
thank you for this video~ i love how this was explained, with lots of examples that make sense! what to do, and what not to do.
Glad to hear it. :)
One question Guy... 13:27 time.. Do you consider the bad use "Get Actor of Class" or you´ve used these one in this case to understand the main reason that is the right use of soft/hard references only???. Thanks you anyway.. Because Iam very worried and I have terrible questions when I invoque "get actor of class"... Only this thing. Very nice content, Congratulations!!!.
Get actor of class is bad in the sense that it will need to go through all the actors to find the matching ones of your query. So as you have larger worlds with more actors, this will be slower.
So it is mainly something you don/t want to see happening often, like in loops in ticks and such.
But if you have it as a "one off", like there is a very specific actor (or actors) you need to gather and you do it once in a begin play in an object or something to gather the references - then it will not happen often and is not likely to be a problem.
Thank you for these great tips. It is really appreciated and well done!
My pleasure! Glad to hear you found them useful!
oh god, I did a customizable character, now I see all parts, all clothes all textures, and materials like hundreds of them are hard references...
The first step is knowledge. Now you can choose how to use it for good. :)
It would have been nice to see how you created the interface.
Aren't that disk size instead of memory size?
No, the disc size shows the disc size, the memory size shows the memory size.
damn that was super useful! Been a dev for a while but never understood this properly, man tackar!
It was my pleasure!
Thanks for the help. It was almost too late.
Glad to hear it was in time!
More of these for sure good stuff Ty
Thank you for the feedback. :)
So basically, if I can associate this with C++ class instantiation, making hard references is akin to calling multiple new calls (or however you create your objects), which means that every time you make your original class, the memory usage of the class will be created, along with every other class you create in the constructor or wherever at initialization time.
Whereas a soft reference, is akin to creating objects ONLY when needed.
Essentially, yes. That is correct.The dependancy chain causes a increasingly larger footprint.
so @11:51 you are skipping the async load altogether since you are not using the completed pin anymore or even the output of the load, so what the point of even doing it?
Use the completed pin or the other pin depending on what your need is, just like explained.
Thank you very much for the tutorial! Great one, subscribed for future videos!
Thank you for the support!
And the worst part, you are wiring your brain with a wrong methodology using castings, karma will back in a dark coat.
" I have seen things you people wouldn't believe...casts on tick events, casts on collision boxes without use it...3 casts inside anim class...."
It could be costly, for sure. Especially if used frivolously. But being aware of it is half the battle won.
Thank you for this, it clears up a lot for me!
Happy to hear it!
This video was the best I’ve found regarding this topic! Thanks! 🎉
Thank you, glad to hear you like it!
Really well explained, however i still have one question about soft references, lets say that I have a weapon system that uses soft references from a data asset for its stats, animations etc. when I swap weapons to a different one, since soft references become hard once loaded, does that mean that all the data from my previous weapon remains loaded? how does this affect memory and how should I organize a system with lots of equipable weapons and tools that each have their own logic and animations? thank you for your videos
When an object no longer is referenced somewhere, the garbage collection will eventually remove it.
I've been doing a fair amount of interfaces instead of casting, but one thing I do is have my enemy cast to my player to store a reference to him on begin play. Is there a better way to do that?
Seeing as your player is likely going to be loaded into memory at all times regardless, this should not likely be an issue.
@@LeafBranchGames That makes sense! Thank you
@@camelotvfx No problem.
very concise explanation.
Thank you!
Thanks man, I figured out the general use, but this async load is new to me. As i understand it, an async loading would produce less hitches when loading into memory more complex stuff, as it's a lower priority load in comparison to standard spawning. Or am i wrong?
Well, sort of. Instead of using the game thread to load in an object, which would cause the game to halt until that is done, it is done in a different thread, so technically a parallell process.
Thank you! I am realizing more and more that most tutorials don't give you the tools to manage your game well.
Do you have a video on player states(or states in general)? Like managing IsSprinting, IsFalling, IsLandingIntoSliding, etc. I am making a system with enumeration. It seems like a good way. Better than boolean spaghetti..?
Not spcifically, not yet. You may want to look into my tutorial on gameplay tags: ua-cam.com/video/edJGE0aidZY/v-deo.html and even if you are not making an RPG, my free RPG course teaches you a bunch of useful things: ua-cam.com/play/PLNBX4kIrA68lz8GSxTQKX_0B23tHP6Bl9.html
@@LeafBranchGames Have been wondering about gameplay tags. I am not starting with an RPG, but I love RPGs:) Thanks mate!
@@erksipa No problem
Thank you. That was really useful, and very well explained. Subscribed.
Thank you for the praise and the support!
What about if i use C++ only and the reference viewer is entirely hard references... (i use just simple * pointers in c++) now i should convert some of the parts into soft references in c++?
Another question, maybe you would know since i can't truly find answer on this, do i have to clear DECLARE_MULTICAST_DELEGATE() macro delegates on object destruction which have delegate?
for example i use static delegate in enemy class when enemy dies it broadcasts to certain functions like WaveManager update UI:
DECLARE_MULTICAST_DELEGATE(FOnEnemyDeath);
static inline FOnEnemyDeath OnEnemyDeath;
AEnemy::OnEnemyDeath.AddUObject(instance, &UWaveManager::updateEnemiesAmount);
and clear like this:
void AEnemy::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
OnEnemyDeath.RemoveAll(this);
}
Thanks for sharing good practices something that can be rare among tutorials haha
My pleasure. You are not wrong!
Is there a way to "Unload" the Async Loaded Asset when no longer needed in memory and then be able to soft reference it and load again? I see that when it is once Async Loaded it will become forever the hard reference for the Player on the moment it is fully loaded from the soft to hard reference, even when later actor is no longer needed it stays loaded in memory
If something isn't referenced by any other object, garbage collection will handle it eventually.
If we want to trigger something in some specific objects in the map with interfaces, should we use get all actors of that class and pass them as targets? Doest that use memory as well?
Preferably, you should not send messages to all actors if it is only relevant for one or a subset of actors. Getting all actors of a class, will create hard references as well.
In the first five minutes you described hard and soft references 100x better and more to the point than it took Epic's own rambling, idiotic "Demystifying Soft Object References" video.
Earned yourself a subscriber.
Thank you for the kind words as well as teh support. :)
So if an asset/actor is already in the map, theres no issue with casting to it right since that asset is already in the memory? thanks!
On that specific map it will not be an issue no. If you also have another map where it is not in, then that would be an issue.
Thanks @@LeafBranchGames
@@uavisionx No problem
Great video!
Thank you!
Would casting be optimal on anything to do with network and replicated values?
In which cases should I use soft references and when not or can I use soft references for each casting (of characters like enemy npcs (or in they cases for the player)) or variable (like animation montage as example)?
This is one of the Best Video, Thank you !! ✨
Thank you kindly!
theres a way to make a soft reference in the material graph? with textures maps
I don't know. I am not as good with material as I would like to be. I would guess no.
TYSM
My pleasure!
Ive watched this 3 times but I'm still confused and have so many questions It almost feels like what Ive learned about ue5 was a lie for the past 2 years What do I do if I want to call a event in another blueprint? Or a function? Ive tried using interfaces but I can never get it to work sometimes. Why spawn an actor when its already in the level? Like when I turn a valve and the water sprinker (which is a different blueprint) to activate a particle? I just got my game design major and there is still so much to learn about ue5
Calling an interface is essentially teh same as calling an event or function in a different blueprint. It is just a bit decoupled.
When you create something, let us say you make a game where you sneak your way to some objective. Then you have guards walking around. It makes no sense to spawn them, because you want to, in design time - in the editor, see the amount of guards and where tehy are. Something that you cant't grasp if all of your guards spawn at the start of the mission.
But if you have something like a zombie game where at some point hordes of zombies will appear to assault the base, it makes little sense to have them all in the level taking up performance until the point they are supposed to attack. Then it makes more sense to just have a place where you spawn these zombies in.
Learning is a journey, it never ends.
Totally relevant for my current project….i’m slighlty scared of what i might find when doing a ref map or size map 😅 thanks!!
Haha. Denial is always one approach as well!
if something exist on the map and you have a hard reference does it store it self twice in memory ?
an analisis on how the system works as total based on this question would be really useful ^^
For example if the helicopter was already in the world before our character spawned
or if two things have a hard ref to something does it mean its loaded twice ?
The question exist multiple times in the comment section.
Does it make much difference if you're hard referencing say the player, who is always going to be loaded regardless?
First of all, many thanks for sharing your knowledge in general and in particular this video, because it's a must-watch. The icing on the cake would have been to include an example of a soft object reference in addition to the soft class reference, other than that, nice job!
I think I'll be taking this video from the opposite point of view of most people watching it because I've been trying to avoid casting like oil and water. Still, this video has proved to me that you don't need to do always the workaround if something is already in memory.
There is one thing that bothers me and I would like to ask you what approach would you follow about it. Let's say you have object A and object B. Object A has some dispatchers and object B wants to bind/subscribe to them but they don't know anything about each other. How would you bind object B to object A's dispatchers without having to cast A within object B? Do you need a third party that knows about them both? Do you create an Interface for object A that just returns itself whenever it is used? How? Any tips on the subject would be much appreciated.
Glad to hear you like it, and that is the correct understanding. If you don't know what will be in memory you should avoid casting to make sure you don't load unecessary things. But if you know what will be in memory, then you can of course work around that.
Regarding dispatchers, it depends on the event you are trying to subscribe to. If it for example is a onDestroy event, then that is something that exist on the actor level, so you only need an actor type reference. If it is a specific event that only exist on a specific class, then there is no way around it, you need to cast to know the type to know the event is there to setup listening to.
@@LeafBranchGames Great Video!what i have some trouble understanding is: let's say we always have an object A loaded in the map and its size is 20MB, if other 2 actors cast to it, will memory footprint increase linearly for each (so +40MB) or it won't because that actor A was already loaded in the map from the beginning?
@@memeproductions4182 It depends, but generally no it will not linearly increase.
@@LeafBranchGames thx for clarifying!
So in short using interfaces instead of direct casting is a good practice right sir? and always try to use soft reference while development got it.
Thanks a lot keep more of these videos coming it helps a lot and now im going to remove cast and implement interface where necessary
Interfaces are great for sure. But not all hard references are bad. If you have a character that always have a specific sword, is never without it, then it would always be loaded in memory regardless. So a hard reference there may not be bad. So there are some circumstances that are not as black or white. But as a rule of thumb, it is a good start!
@@LeafBranchGames yeah again thanks a lot for make it easier for everyone keep more of these videos coming. Who knows what other deal breaking mistakes I have made in my game 😂😂😂
@@gokuvinod2850 Ha ha, will do. :)
Video was useful although at 0:38 you say you will talk about components and then later in the video you say you won't cover them in this video which is a tad frustrating!
I get that. Sorry! Didn't mean to imply I would get into depths about components, but I can totally understand the misgiving. I may expand on it further in another video to compensate.
@@LeafBranchGames that would be great! Re-reading my comment I should mention that the information given in the video was great and distils the benefits of soft references very efficiently. The video definitely is a good reference even if it didn't cover the entirety of what I was expecting from the intro!
@@sinksinkswim Glad to hear it was not a total drag. :)
Throwing some shade with that thumbnail? lol
It's also worth mentioning that casting to a C++ class from a blueprint is free from a memory standpoint. So say that you have your character largely defined in your C++ class for example, casting to it from Actor/Pawn whatever in a blueprint does not increase the memory footprint of the blueprint where the cast is performed.
Is that true? That feels like it should not be the case from an objective stand point. I will have to check that out. Thanks for sharing regardless!
Shade where shade is due!
First of all, thanks for this really nice and needed resource. I would love to ask you something. When you show the size map, the default option shown is the Disk Size, but you keep reffering as the space in memory.
Should we change the tab from disk size to Memory size (or whatever name it is, sorry, I am not in UE right now) to really see what is going on? Or with Disk Size is more than ok?
Again, many many thanks.
Both disc size and memory size will both increase with references. If you are looking to really min max how much is used by your RAM, then the memory size is what you want to look at as a measure. If you are just looking to reduce dependancies of assets, then either view is ok to look at because you are just looking to decrease references as much as you can, maybe not shooting for a specific target value.
@@LeafBranchGames Thank you so much!!!
Thanks for the video, it's really cool. Though, any suggestions on actual player blueprint size, for example? I mean, let's say I have an ULTRAKILL-sized game (in terms of mechanics and code complexity). Is there any recommended player blueprint size for a game like that? Right now, in my prototype, the player blueprint weighs ~150MB (of which most of it is taken up by the UI), and I don't know if that's a good or bad result.
P.s. I use hard references in some places, and soft references in other places, according to the situation.
Not really. It depends on the situation and what you are trying to accomplish. A really light weight game has the benefit of being able to be loaded very quickly. A game with a lot of dependencies will take a long while to load but on the other hand you have those assets available for quick use now. It also sets the minimum requirement of your player base.
Please continue making your how to be better game dev playlist series
Will do!
I remember I was trying to do the invoker from dota into unreal engine... and omg I was like why is my game soooo laggy.. I'm pretty sure all the balls like in invoker I made them have a hard reference to the player and also reference to the meshes for the skills hahahha and you multiply that by 3 and it get worse. I think lately I'm trying to have most of the logic into the player controller because I can used the "get pawn controlled" also for things like in the widgets I use those functions. I didn't know about the "cast to..." also count as a hard ref so that's good to know thanks :D. Another thing I do is that because using interfaces it gets a bit messy and then you don't know if you are adding the correct function to the interface, what I do is making all custom events first and when I get all clean and looks nice I have a better picture to then created the blueprint interfaces and then I just update the custom event calls, a bit long work but the thing is that you work faster in the first part
Edit: damn... so I just realized if you have different cast to different blueprints... that means you're basically adding hard references for all those blueprints?
That is indeed what could happen. You can have a cascading effect of hard references causing all of the assets to be loaded despite not even using them at all.
Doing custom events and then replacing with interfacing is fine. We don't always know how things will turn out code wise, so refactoring the code is a good thing.
Now, how do I do this in C++
You can see how it is done in C++ here: docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/Assets/AsyncLoading/
I have a question... When I use a hard reference to something that is already loaded into memory (etc. GameMode class), is it harmless?
So just so im 100% clear, on the reference viewer:
If an object is on the right hand side of the viewed object (downstream), it will get loaded by the currently viewed object
But if its on the left hand side of the currently viewed object (upstream) it won't get loaded by the currently viewed object?
Does multiple references to a single actor multiply the memory use? Or is this information stored as a global variable of some kind once its cached?
If you have one actor that is referenced from different places, that should not be causing it to be loaded multiple times.
Excellent. Thanks for clarifying. @@LeafBranchGames
@@LimitedPerfection No problem.
If I have 2 assets with hard references to a third asset, will that third asset still only be loaded once? Also, if I have a small one-room game (ie something quick for a game jam) and almost every asset has been placed in the room from the start, is there a benefit to not using hard refs outside of trying to use best practice?
Not really, no.
great video!
Thank you!
Great video! Learned so much 👍
Really happy to hear that. :)