UE5 Understanding hard and soft references - Be a better game dev
Summary
TLDRIn this episode of 'Being a Better Game Dev,' the focus is on hard and soft references in game development, specifically within Unreal Engine. The video explains the difference between the two, with hard references loading all dependencies into memory, which can lead to high memory usage, while soft references only load assets when needed, reducing memory footprint. The tutorial demonstrates how to use both types of references, the impact on memory, and how to use interfaces and components to manage dependencies efficiently. The host also discusses the trade-offs between speed and memory usage, offering practical advice for optimizing game assets.
Takeaways
- 🔗 Hard references in Unreal Engine load all dependencies into memory when an asset is loaded, which can increase the memory footprint.
- 🔗 Soft references allow for assets to be loaded into memory on demand, reducing unnecessary memory usage.
- 🔗 The memory footprint of an asset can be viewed using the 'Size Map' feature in Unreal Engine, which helps in understanding memory usage.
- 🔗 Hard references can lead to a cascading effect where multiple assets are loaded into memory, even if they are not immediately needed.
- 🔗 Soft references are indicated in the reference viewer with a purple line, as opposed to the white line for hard references.
- 🔗 Interfaces can be used to interact with assets without creating hard references, thus avoiding unnecessary memory load.
- 🔗 Components can be utilized to offload functionality and reduce hard reference dependencies within assets.
- 🔗 Hard references provide faster access times since the assets are always loaded into memory, but at the cost of increased memory usage.
- 🔗 Soft references require additional management to ensure assets are loaded into memory when needed, but they help in reducing the initial memory footprint.
- 🔗 The choice between hard and soft references depends on the specific requirements of the game assets and the desired balance between memory usage and access speed.
Q & A
What are hard references in the context of game development?
-Hard references are direct links to assets or objects within a game engine, such as Unreal Engine. When a blueprint or asset has a hard reference to another asset, the engine loads that asset into memory, ensuring it's available at runtime. This can lead to increased memory usage if not managed properly.
How do soft references differ from hard references?
-Soft references do not force an asset to be loaded into memory at the start. Instead, they allow for lazy loading, where the asset is only loaded when specifically called for, thus potentially reducing the initial memory footprint of a game.
What is the memory footprint of an asset with hard references?
-The memory footprint of an asset with hard references is larger because all referenced assets are loaded into memory when the main asset is loaded, regardless of whether they are currently needed or not.
How can you check the memory footprint of assets in Unreal Engine?
-In Unreal Engine, you can check the memory footprint of assets using the 'Size Map' feature, which provides a detailed breakdown of the memory usage for each asset and its components.
What is the Reference Viewer in Unreal Engine and what does it show?
-The Reference Viewer in Unreal Engine shows the dependencies of a selected asset, with hard references depicted by white lines. It helps developers understand which assets are being referenced by the selected asset and which assets reference it.
How can interfaces be used to avoid hard references in game development?
-Interfaces can be used to avoid hard references by allowing for communication between assets without directly linking them. This way, an asset can call a function or event on another asset that implements the interface, without needing a hard reference to that specific asset.
What is the impact of having many hard references on a game's performance?
-Having many hard references can lead to increased memory usage and potentially slower performance, as the game engine loads all referenced assets into memory, even if they are not currently in use.
How can you manage hard references to optimize memory usage in game development?
-To optimize memory usage, developers can use soft references, implement interfaces, or utilize components to offload functionality. This allows for more control over when and how assets are loaded into memory.
What is the difference between object references and class references in Unreal Engine?
-Object references are direct links to instances of classes, while class references are links to the class itself. Object references create hard references, whereas class references can be used to create either hard or soft references, depending on the context.
How do soft object references and soft class references work in Unreal Engine?
-Soft object references and soft class references in Unreal Engine allow for referencing assets without loading them into memory immediately. They can be used to load assets on demand, reducing the initial memory footprint but requiring additional management to ensure assets are loaded when needed.
Outlines
🎮 Introduction to Hard and Soft References in Game Development
This paragraph introduces the topic of hard and soft references in game development, specifically within the context of Unreal Engine. The narrator discusses the impact of these references on the memory footprint of game assets. The video aims to explore how these references function, their advantages and disadvantages, and how they can be managed to optimize memory usage. An example is given using a third-person character and a helicopter asset from the Vigilante asset set, which is added to demonstrate the concepts. The reference viewer in Unreal Engine is highlighted as a tool for visualizing these dependencies.
🔗 Understanding Hard References and Their Impact on Memory
The second paragraph delves into the concept of hard references. It explains that hard references in Unreal Engine cause all dependent assets to be loaded into memory when the main asset is loaded. This is illustrated by adding a helicopter asset to a third-person character, which results in an increase in the memory footprint as observed in the size map. The paragraph also discusses the reference viewer, which shows the dependencies and how they are loaded into memory, leading to potential memory inefficiencies if not managed properly.
🔄 Transitioning to Soft References for Memory Optimization
The third paragraph introduces soft references as a way to manage memory more efficiently. Soft references allow for the referencing of assets without immediately loading them into memory, which can help reduce the overall memory footprint. The narrator demonstrates this by creating a soft reference to the helicopter asset within the third-person character blueprint. This approach requires manual loading of the asset when needed, which is shown to be done asynchronously. The difference in the reference viewer between hard and soft references is also highlighted, with soft references depicted in a different color to indicate their nature.
🔄 Utilizing Interfaces and Components to Avoid Hard References
The final paragraph discusses strategies for avoiding hard references, such as using interfaces and components. Interfaces allow for communication with assets without creating a direct reference, thus avoiding unnecessary memory loads. The narrator demonstrates this by creating an interface for the helicopter asset and using it within the third-person character blueprint. This approach keeps the memory footprint low while still allowing interaction with the asset. The paragraph concludes with a summary of the benefits and drawbacks of hard versus soft references, emphasizing the importance of managing these references to balance memory usage and performance.
Mindmap
Keywords
💡Hard References
💡Soft References
💡Memory Footprint
💡Blueprints
💡Asset
💡Reference Viewer
💡Interfaces
💡Components
💡Spawning Actors
💡Asynchronous Loading
Highlights
Introduction to the concept of hard and soft references in game development.
Explanation of how hard references affect the memory footprint of assets.
Demonstration of using the reference viewer in Unreal Engine to check dependencies.
Impact of hard references on loading assets into memory during runtime.
Example of adding a helicopter asset and its effect on memory usage.
How to identify and manage hard references to optimize memory usage.
Introduction to soft references as a way to reduce unnecessary memory load.
Practical example of creating a soft reference to a helicopter asset.
Comparison of memory footprint between hard and soft references.
Explanation of the difference between hard and soft references in terms of speed and memory usage.
Technique for using interfaces to avoid hard references and reduce memory footprint.
Example of implementing an interface to interact with a helicopter asset without hard referencing.
Discussion on the trade-offs between using hard versus soft references.
Strategies for managing references to prevent excessive memory consumption.
Conclusion and call to action for developers to continue learning and optimizing their game development practices.
Transcripts
[Music]
welcome to an episode of being a better
Game Dev so in this episode we are going
to be checking out things like hard
references soft references we're going
to be talking about what they are how
they function we're going to be checking
out how the memory footprint of our
different assets are affected by these
things we're going to be checking out
how references hang together and how
pointing at different objects cause a
cascading effect if we have hard
references and how we can make use of
soft references to avoid this we're also
going to be checking out some different
things like interfaces and components
talking about it a little bit and see
how we can use that to offset a few of
the disadvantages of these things as
well so stick around and check it
out welcome back so in this video we're
going to be talking a bit about hard
references and soft references what they
mean what's good and bad about them H
how they work and also
some workarounds to to avoid the the
worst offenders so um starting off in
this is a third person template project
uh so it's just a third person character
that's running around uh when we start
and I have done a few things in this
project I have added a asset in this
case I've added a helicopter from from
the Vigilante asset set it's available
for free on the marketplace if that's
something that you want um I have added
a little bit of code to our third person
character not a whole lot we'll go
through it once it's relevant we have
added some code inside of our level also
very small amounts and I'll go through
that when it becomes relevant as well um
but starting off what what does it mean
to have hard and soft references well if
you take a uh blueprint for example or
any asset in Unreal Engine you can go
and check the reference viewer the
reference viewer gives you this or a
very similar view uh what this means is
uh this is the blueprint in this case
that we opened up and all the things to
the right over here are assets that uh
are being used by this
blueprint all the assets to the left are
are things that make use of this uh
character in this case so everything on
the right is dependencies for the
character and everything on the left is
something that has a dependency of the
character uh so uh how this works is
each of these lines represent a a um a
dependency in the form of some kind of
reference in the case here we have white
uh lines and these are hard references
so a hard reference means that Unreal
Engine when it loads in a blueprint
third person character in this case it
loads up all its hard reference
dependencies and loads them into memory
so that it can access them whenever
they're needed in runtime um this will
show up for example if you go to uh
let's go to our content folder and we go
and right click on it and we say size
map our size map here in this case
consists
of 208 megabytes of memory taken and of
these 208 megabytes you can see what the
different aspects of this character uh
the memory is being used for so we can
see that our skeletal mesh is here and
it it uses
2.7 megabytes and it consists of these
boxes that are consisting inside of it
etc etc so we we have a few different
boxes here that represent the different
usages for our character in this case um
now when we have a reference in our
character so if we were to go to our
character and let's say we create a new
variable so
remember in our size map we had 28
megabytes if we have another uh variable
here and we make sure to choose BP West
which is the the helicopter in this case
and I say I want to have an object
reference or a class reference these are
both hard references so if I click one
of these and I compile and I save and I
go back to our content
browser and I check size map you can see
now that it's going to be 392
mbes so just by having that reference in
our character it now says to on engine
that this is something I have a hard
reference to this is something I need to
keep track of so you need to load this
into memory as well when I get loaded
into
memory and if we go to our reference
viewer you can see here that we have
these assets over here that we're
depending on or that we are yeah
dependent on these are the ones that we
load in and in the bottom here we have
our context for default if we were to
refresh this now you can see that below
that context we get now our helicopter
so now we have a hard reference to that
other blueprint and this is in our third
person character so what this means is
when we open up this map or when this
game mode gets launched H either of
those say that they have a reference to
this character which will then load in
the character and all its dependencies
which means all of these things and that
in case in this case means that we load
in this helicopter as well and if we
double click into that we can see that
it has a set of dependencies as well
that it needs to make use of right and
you can also set the search reference
depth here to something higher so if we
were to do three or something like that
no apparently not this the dependency
depth I
guess it's taking a little bit
um this might be a little bit bloated
for us to actually uh get a good
overview of but essentially here you can
see how this tree sort of uh grows with
each level so there are probably further
dependencies here that are all loaded in
once this blueprint character is loaded
in uh so so it's easy to see I hope that
if you have hard references to a lot of
different objects H you will be loading
in a lot of different things a lot of
different assets and note that this is
my third person character and my third
person character
is inside of this map but despite the
helicopter not being here it will still
be loaded into memory so it's completely
unnecessary in this case
right so we're using up a lot of memory
for no reason in this case so we're
going to be uh removing that helicopter
for
now like
that now hopefully you have a basic
understanding of of hard references and
how it sort of works let's take a look a
little bit at soft references so if we
go into our third person character and
we go in and create a variable and we
call it
helicopter inside of here we can choose
to have the type
actor and of these we have the two hard
reference versions up here object and
class we have to have two soft object
references in the form of a soft object
soft object reference and a soft class
reference so if we wanted to spawn in a
a another blueprint in the world another
class we could take the soft class
reference uh in our type we can have
actor but then as a soft object
reference type class we can choose to
have for example our
helicopter so this means that it will
take the footprint of an
actor but it can reference a West
helicopter in this case
so if we go and check our uh character
uh let's see we go over here blueprints
we can see that our size map is the same
it's 208 still it hasn't been affected
by this because it's just loading
another actor and it only it already
knows about actors because we are an
actor uh using this reference now we
could spawn it into the world but we
can't spawn it in just straight up
because if we do this and we say uh
spawn actor from CLA
it's going to be running a conversion
from our soft reference to this uh but
this being a soft reference means it's
not loaded into the world so we have to
manually tell it when to do so which
means that when we press here for
example on our press 2 key we can say
asynchronous
load um
assets class asset
like so this means that we will now tell
it at this point here to load in this
asset so it won't take up memory until
we reach this point it will however be
of the base type object class instead of
an actor which is needed for spawning an
actor so we can't just hook it up like
so so we could either cast it to an
actor and then hook it up over
here uh but and of course we would have
to do the okay this is not what it
wanted I meant to do this cast
actor like so
no cast
actor close there we
go and if we hook it up like so it we
would be able to uh spawn it into the
world the asynchronous means it's going
to be loading and be done at some point
which means that we have two execution
pins here we have one pin for when it's
starting and when for one is completed
so in this case I would want to hook up
to the completed one to say that okay
once we have loaded into memory then we
want to spawn the actor so if we were to
go to
our map here and press the two key and
then I eject from here I can see that
the helicopter is over here so we focus
on it and here we can see the helicopter
so we're spawning it into the world now
properly and everything is fine but our
third person character is still going to
have the the memory footprint of 208
megabytes like when we started the
reference viewer now is going to be a
little bit different if we refresh the
reference viewer we're going to be
seeing here now that we have our
helicopter here like before but we now
have a pink purple kind of a line
instead of a white so this means that we
have a a soft reference to this object
so it's not necessarily needed to be
loaded in once this asset is loaded into
memory okay uh you you could also
instead of just casting this actor you
could just hook it up like so and this
would work as
well uh because this conversion is
similar to the cast essentially so if we
do this eject go here and focus on it so
you can see the helicopter here is being
spawned okay all is good and fine so far
I hope
so with a soft reference like this we
won't take up as much memory uh and we
will have a different uh relationship
when comes to the reference viewer in
what kind of assets will be needed to
load in but we have the detriment of we
need to choose when to actually load an
asset in when we feel it's going to be
needed and of course this means that we
might need a little bit of time to do
this depending on what kind of asset we
load in so that might be something that
you want to consider as
well um the the differences between a
soft and hard reference when it comes to
accessing them is that a hard reference
is going to be faster uh because it
already has loaded it into memory so
it's available a soft reference if you
make use of it needs to first check and
see if it exists before it actually can
access the the object that it's
referring
to uh but but of course you have the
memory as a offset for for that benefit
then so the the speed over the memory
and how do you combat this kind of
situation uh other than using soft
references how do you avoid uh hard
references like this well let's take a
look at the code that I have prepared so
in our level we
have if we go and open up our level
blueprint here's our level blueprint uh
we we're getting the third person
character we're calling two events on it
event one and two these are the ones
that we see up here and they take in an
actor as an input in our map currently
we do not have an actor referenced here
but let's say that we had our helicopter
in the world here or this could be some
other asset of course as well so if we
go to our third person map here we can
say that we want to create a reference
to the helicopter and we say that we
want to send that as an input to our
events
um what's happening here now is that in
our third person character we're getting
these events sent to us when we press
the key and we get an actor here and
let's say we wanted to do something with
the helicopter in the helicopter we have
a little bit of code we have an event
that says helicopter event and we have
an interface called helicopter interface
event when the event is called the
helicopter event we print out that the
helicopter event has been triggered when
the interface gets called we call in
this event and say the same thing
essentially
so if we were to go to our character now
compile save and go here and check the
memory
map we can see that it's still at 208
but the moment we say okay we want to
make this a cost to BP
West so that we are able to make use of
the helicopter
event helicopter event there we
go so now if I were to go in here and
play I press one we can see that the
helicopter event is triggered is printed
up in the the top left over
there uh but now that we have had added
this cast to our class that means that
we have now created our hard reference
so if we go to reference viewer we can
see that it's back here with a white uh
line and it's again going to be taking
up memory for us for our character
because we're forcing it to be loaded in
now so this way causes us to create a
hard reference and even if we didn't
have this helicopter in the level just
the existence of this cast would say
that this blue print this third person
character needs to have this helicopter
loaded into memory to be able to
function because we have this cost it's
a hard
reference if we remove this and instead
say we want to call on the
helicopter let's see here
helicopter interface event so this
one is calling on an actor saying we
want to call the helicopter interface
event and since it is an interface it
will work if it has the interface if it
does not have the interface it will do
nothing uh the interface itself will
again if we go in here and I press one
you can see that the helicopter event is
being triggered because we are calling
the helicopter interface event which is
calling the helicopter event which is
calling the print string now if we go to
our reference viewer refresh our
character can see we have a soft
reference to our helicopter which is of
course from our helicopter over here if
we were to remove this compile and
save refresh our reference can see that
we don't have a a a um dependency to
anything except for our BPI here and
that one is just being used by
helicopter it's not actually a reference
or a dependency for the helicopter so
this this way we don't load in the
helicopter at all we don't have a hard
reference to it we don't have a soft
reference to it we still able to uh
access the code in it and if we check
the memory we can see that our size map
is 208 as well so an interface is one
way to circumvent having hard references
and avoid uh both the the hard reference
um dependencies and also the memory
footprint of your classes you could also
do things with uh things like components
and stuff and offload things that way uh
I won't be showing that off in this
tutorial however
anyway uh that is
hopefully understandable and it's the
the sort of core concept of of hard and
soft references um so the benefit of
hard references again you're going to be
having faster access time T because you
always have the object available for you
when you run um the payment for it is
that you have to load everything into
memory and that could be easily getting
out of hand if you have a a lot of
reference in because again if you have
your reference viewer here you have
let's do it like this we do a now let's
do the cost we do a cost DP helicopter
no not where helicopter there we go so
in this case here we have the cost which
means that we have a hard reference
which means that it it is available here
and if this helicopter in turn had a
cost to let's say another helicopter
then that helicopter would be loaded in
and let's say that helicopter had I
don't know a missile or something loaded
as a direct reference the tree just
expands and explodes if you don't keep
track of how you're making use of your
different references so that's why it's
easy that the memory consumption can
just get out of hand when when doing
this so the soft references are of
course a better choice when you're
having certain objects that you don't
need to have available at all times so
it sort of depends on what kind of
object that you're working with some
things you will know that you always
have reference uh a a need for and then
having a direct reference a hard
reference is is fine of course because
you're going to be needing to access it
at at all points or at any
point so the soft references allows us
to have a a smaller memory
footprint uh it comes at the cost of
being a little bit more finicky to work
with since you need to make sure that
you actually load it into memory before
you spawn it into the world or interact
with it
anyway and such and uh you have some
options of circumventing hard references
as well using things like interfaces and
components and such as well so that's
going to be all for now keep on learning
take
care a big thank you to all of you who
like comment subscribe and share my
videos or through other means support
this channel you are what makes this
channel grow and become a resource for
other people to learn from
Посмотреть больше похожих видео
Life Cycle & Reference Counting | Godot GDScript Tutorial | Ep 1.2
String Builder | Java Placement Course Lecture 13
SMART POINTERS in C++ (std::unique_ptr, std::shared_ptr, std::weak_ptr)
Pythons Object Reference
Variables in C++
L-3.1: Memory Hierarchy in Computer Architecture | Access time, Speed, Size, Cost | All Imp Points
5.0 / 5 (0 votes)