There is no “Get” Game Instance on BP so I use casting. Is casting Game Instance to get values on it on an enemy BP that will be destroyed later also always loads the enemy BP? So let’s say when on a zombie BP and I use cast Game Instance, will the zombie BP be always loaded or just the Game Instance?
As soon as a casting class loads, all classes it casts to are loaded to memory if not already loaded.
The zombie blueprint would only always be loaded if you casted to it from the game instance. You can look at the size map of your game instance blueprint and see everything that will be loaded when it’s created, the zombie bp won’t be there. If you look at the size map of the zombie bp you should see the game instance there since the zombie bp casted to it and expects it to be loaded.
If you wanna avoid that cast altogether, you can use an interface and “GetGameInstance” to get the generic game instance class, and call the interface function on that, completely decoupling the two classes.
Casting to blueprints of the game instance are probably the least likely to cause an issue. Since the project can only have one game instance type and it persists for the lifetime of the application, it’s not actually possible for other blueprints (like your enemy blueprint) to be the root cause of the game instance blueprint being loaded. You load any other blueprint, the game instance will already have been created.
The interface solution could be okay if multiple classes will implement it. But if only the game instance implements it, that solution is rather silly (IMO).
The other solution would be if you know C++ and have a native implementation of your game instance that provides the functions (or at least the BlueprintImplementableEvent) that you can call from blueprint.
In that case, then Isn’t it okay to use casting on Game Instance and make it always be loaded because it’s already loaded when you start the game and it’s already always there to begin with? Like a Player Character BP? or not?
Using game instance is very cheap and performant. You usually create variables and assets in the instance that are always going to be used in the project. Basically, game instance is like having “global” variables.
In any blueprint where you need them, on begin event cast to your game instance and promote it to a variable. Name it “Global variables”.
Does having ten 4k textures in game instance (for example) allocate as much memory every time you cast to a game instance. No. You are just getting a reference to it, it does not allocate extra memory.
There are varying degrees of okay. If the sizemap of your Game Instance blueprint is small and doesn’t have a lot of it’s own dependencies, then yeah it’s probably okay. And if your game instance is only doing things that are reasonable for a game instance.
But it can make it harder to reason about the sizemaps of any blueprint that references your Game Instance blueprint. Especially if your Game Instance is doing weird things like managing UI or inventories (real things I’ve seen people do). Of course then your problem is the Game Instance and not the reference that you’re introducing from the other blueprint’s cast.
And It can also be an issue for the Editor where those classes wouldn’t be guaranteed to be loaded already. You can cause yourself issues where in order to open up one blueprint, your editor has to load every other blueprint of your project. Which is bad.
I try not to treat the Game Instance as too much of a special type. I’d rather work with it exactly the same way as any other class with minimal assumptions about when it’s loaded. But I’m also a C++ developer, so I have a few extra tools (like native base classes and subsystems) that allow me to build gameplay without these reference problems.
Especially if your Game Instance is doing weird things like managing UI or inventories
Where else would you keep the inventory?
If you are building an large scale mmo or something like that, game instance is not enough. You would need to use that Unreal database thing no one understands. If you are building a small or medium size game with couple hundred items, its ok to use game instance for variables (arrays and structures). It is not wise to create textures and such in a game instance. Even for a small inventory. Edit - maybe if you create a soft reference texture. Then it may be ok.
Almost anywhere. Probably some Actor that more accurately represents some game data. Even if it’s not a Character of some kind, you can still create new actor types to represent things like the overall player progression in your game and give that actor some kind of inventory.
But that’s getting a little bit off the topic of the thread.
But if you need it to persist?
Then you must insert that actor (inventory_bp for instance) in every level. And you would have to save any changes while playing (unlike game instance you would need to save them immediately, not only on save game or autosave or checkpoint save or quicksave) and load them on every new level start(which is what you also do with game instance but only once at the start of a game). So, yes - having inventory variables (arrays of structs, integers, floats,etc..) in game instance for a simple/medium inventory system is ok.
The two best options here I think are: 1) seamless travel (you can send actors from one world to the next) or 2) leverage your save game (you construct a save as you exit one level and load it when you enter the next). I’m not sure how accessible seamless travel is to blueprint only projects.
If you absolutely have to, maybe for temporary expediency, you could copy info from your game to the game instance and back again. The point would be that your runtime gamestate doesn’t exist on the game instance and that you try to move to one of those other two better options. I like the save game option because it provides a good way to exercise your save games without actually having to make manual saves all the time just to test things. When saves break, your level transitions break and you fix it quickly.