I am writing an inventory system using AssetManager and have encountered a very frustrating thing: the inability to retrieve data without loading.
There is this code:
Yea. I’ve hit similar problems. What I did is really stupid but it kinda worked.
Take part of the data from all items in a separate sruct/object that is pre-loaded. I’ve used such structs for “item menu data” containing icons names and prices (in your case might be stack size). The actual materials, meshes, animations, vfx and sfx of those items were only loaded when the player “equips” them but I could always access all needed visuals for any menu.
Ok. I’m not sure I can explain myself any better but I’ll try to do it again anyway…
You can never retrieve data that has not been loaded. Period. You need to load the asset to access its fields.
If however, your data assets are too large/slow to load you can probably split them in two parts - a “heavy” part and a “light” part.
Further, you can take all the “light” parts of all you assets and place them in in a single object which is loaded at the stat of the game - pre-loaded. For you this might be just a list of stack sizes. The “light” parts might have weak links to the “heavy” parts to facilitate loading “the rest” of the asset when needed.
I’m not saying this is the only solution but it is the one that has served me best in the past.
You can always load everything upfront during the “loading” of the game/level or figure out a clever way to load assets asynchronously just before they are needed (this depends on your project though)
You’re actually already using the solution for your ItemCategory member and that’s to make it AssetRegistrySearchable. In addition to the nice editor functionality that gets you, it also allows you to query that information from code about the asset while it’s unloaded!
However, I don’t think this really scales very well. Invariably, you/someone wants to check almost every value “without loading the asset” and suddenly every member is marked as searchable and I don’t think that’s a good place to be in. Also some members are more or less difficult to actually check using the searchable registry interface.
My real suggestion is similar to dZH0’s and goes along with the other tool that you’re already using which is AssetBundles which sounds like a weird solution but stay with me for a second. Since all the really expensive things like meshes, textures, blueprints would be soft references on a bundle, instead of breaking up the PrimaryDataAsset into multiple assets so you can preload part of one just preload the PrimaryDataAsset. Let it be loaded for the whole duration of your game and uses the bundles to load the expensive bits as you need them. Compared to those parts, the rest of the PDA is small and even if you have lots of them the memory cost to having them loaded really isn’t that big of a deal. You also don’t have to worry about moving data between structures as you decide which data should be preloaded or not. It also works out nicely (I think) with game features because you can match up the loading behavior with feature activation. Then when you want to enumerate all instances of a certain primary asset type, you just get all of them and you get free filtering of only assets from active features!
You can decide if “preload” means before the main menu, or before going into the game proper from the main menu. But the details and differences there aren’t that big.
This is the approach we took for both XCom2 and Marvel’s Midnight Suns. It’s also the approach that I’ve put together in my asset plugin that I put up on github last summer here.
As with all decisions with this sort of thing, the answer is always “it depends”.
You’re never going to load all your PDA’s at the start of the game since, at the very least, your maps wouldn’t be loaded and they’re a primary data asset type.
Generally you might choose to load certain types of PDAs, or a certain type and all it’s child types. And you might decide you don’t need to preload assets of another kind. Even in the one I’ve written and linked to, I don’t load PDA’s in features that are inactive.
The Game Feature System loads it’s PDA that you have to put in feature plugins as the engine starts up and they’re loaded all the time in order for the engine to know what features are available.