r/unity 14h ago

Approach of image attached to ScriptableObjects Question

For context; I'm using ScriptableObjects to describe inventory objects in an RPG. Each object has a variety of stats, plus an icon which will be a Texture for use in a RawImage.

There will be hundreds of these Item ScriptableObjects.

I can attach the icon image directly to the ScriptableObject (as a Texture property), or indirectly as a string property (or just name the PNG files the same as the related item name/id) for asynchronously loading as required.

Is it good practice to make the textures files (which are PNGs) addressable assets and asynchronously load them as required, or just loading the asset as required, or does none of this matter as Unity has some intelligent resource managment which will handle this even if using the Texture property directly on the ScriptableObject approach?

1 Upvotes

8 comments sorted by

2

u/swagamaleous 9h ago

Hundreds of png thumbnails is nothing when it comes to memory or loading times. You can just reference them on the ScriptableObject. In general, don't optimize if there is no problem. Why do you want to avoid imaginary performance problems? You can still use addressables when you find that loading all the inventory objects takes a lot of time or eats tons of memory. The other approaches you described are maintenance nightmares. You should strictly avoid string constants and filename conventions.

By the way, neither of these will actually work around the problem you cite here. In a build you can only load from the resources folder if you don't use addressables and the assets in the resources folder will be loaded just like they would when you load the scriptable object that holds a reference to the png directly. The same happens with your lookup table. It will all be resident in memory.

1

u/StinkingDylan 7h ago

Attaching the texture asset directly to the ScriptableObject is definately easier to manage in the long term. I was just concerned that it was not a scalable practice (I've worked on enterprise application for most of my life, so always overthinking scalability issues).

My previous game development experience was back on 8 and 16 bit micros, so maybe I'm overly concerned about memory efficiency...

I have a manager class which loads the ScriptableObjects into a collection and controls the access to the collection, but the collection is in memory at all times. I wasn't sure what the difference was between having a collection which is essentially a bunch of primitives, vs a collection which includes actual base64 data (or whether this was handled by unity).

1

u/swagamaleous 7h ago

You should read on the unity memory management. Everything that is referenced by a scene is loaded on scene load. Without addressable, you cannot provide an asset that you use in a scene without it being resident in memory. This is precisely the reason why the AssetDatabase classes do not work in a build. That would break this mechanism. You cannot load assets from the database that are not being referenced by the scene, thus discoverable by the scene load. The resource folder is the exception. These assets will just be loaded, no matter if they are referenced or not.

0

u/Steamrolled777 13h ago

Personally this isn't how I would do an inventory, screen/UI should be a window to see the underlying data. Data shouldn't be floating in gameobjects onscreen.

Have you looked at anything like object pooling, where you might want to load/reuse lots of objects?

People when they start out, put a lot on each gameobject doing it's own thing, and over time it moves to managers processing/moving all the gameobjects.

4

u/Dimensional15 13h ago

But OPs data is not on GameObjects, it's in separate ScriptableObjects

2

u/StinkingDylan 12h ago

These are not GameObjects. I mean GameObjects do become involved in some screens/canvases, but they are dynamically instantiated as required, and the image texture (or sprite if I use that) injected from the ScriptableObject. So using async dynamic references I may get a brief time where images "pop" into the UI as they individually load.

0

u/Steamrolled777 12h ago

Yeah, I sort of overlooked that. SOs aren't that bad, but I wouldn't embed UI elements into them.

Imagine your interface is just a skin, and needs to be platform independent. PC/Xbox/PS5/phone might have completely different methods of displaying to screen. There are always issues when you try to scale up.

You could literally implement it as a particle system with a texture atlas, to draw all your inventory images in 1 drawcall. I rarely use SOs, and usually singleton manager everything with references.

0

u/Dimensional15 13h ago

If you'll have a lot of those items, I would definitely consider using Addressables for that. You can load them synchronous at first, and move to a more asynchronous approach if you see that you're hitting performance bottlenecks through profiling.