- Home /
Random textures, ScriptableObjects or Resources?
Hi, I am in a project where we generate random NPCs. The thing is that, for changing the texture i was using a ScriptableObject where i reference all posible textures of the character and then i choose one randomly. The problem is that now we can also change randomly the texture of a lot of other things, and i am watching that people usually use the resources folders for this kind of things, so should i stop using scriptableObjects with arrays of Texture2D references and start using the resources folder? What is the difference?
Answer by Azurelyte · Aug 13, 2020 at 06:15 AM
In my humble opinion, the answer is the enigmatic, "it depends". This is going to be more opinion than anything...
Texture References
If its only a few textures per thing, and you have the budget to keep all the textures in memory, then its fine. Having a list of referenced assets is an easy way to ensure that you don't run into issues with naming or loading the texture. However, once you reference your scriptable object in a scene with all those texture references, Unity will load them all and keep them in memory (even between stoping and starting play in the editor!). I tested this by referencing about 100 textures in a scene through a ScriptableObject and watched Unity eat up about 200mb of memory in the profiler. If these textures are constantly needed and you want to keep them around, this is a good option. If not, this is a terrible choice.
Resources
A better choice might be to load them out of the Resources directory. This way you can make use of the garbage collector to free stuff you don't need anymore. Especially for sets of things that are only used from time to time. One issue will be naming. You will need to enforce a naming scheme on the artists to avoid issues, and keep those strings in the scriptable object instead of Texture references. Your big benefit will be more control over assets and memory.
Streaming Assets/Other
There is a third option. You could pre-compress all of your textures and place them into the streaming assets folder OR ship the pre-compressed texture assets outside of unity all together and load them as needed using .net libraries and Texture2D.LoadRawTextureData(). The nice thing with this is that unity won't preform any hidden operations on those files, and you could potentially change these assets and push those changes to builds of the game without recompiling. Like with using the resources folder, you will need to take special care with your naming schemes. The big benefit here, is that you gain control over what format each texture is in and how its loaded. In my day job, we also use the build pre and post processes to cut assets out from being included to minimize the build size. It should be obvious that this requires a large time investment to make work.
So in summary and in my opinion...
Texture References == easy but less control and prone to gobbling up memory.
Resources == some control and minor annoyances to artists, but you should be able to manage memory better.
Streaming Assets == Gigantic pain to make work (especially on more than one platform) but you get the most control.
If this is just a small school project or quick prototype, I wouldn't worry, pick whatever is easiest for you and your artists. If your looking to ship a product and you want to provide the best experience possible, consider the latter options. The over arching difference is the amount of control that you get over the texture assets versus Unity. Though at the end of the day, your just dealing with different ways of loading data.
Thanks man for that detailed answer, as i said to @Hellium i decided to try the addressable assets, I'm gonna try it, and see if i can make it work.
Answer by Hellium · Aug 13, 2020 at 08:10 AM
To complete @Azurelyte 's answer, there is a 4th option: Unity Addressable Asset System.
Instead of having direct references to objects (your textures), you have their address. An address identifies the location in which something resides.
You have more control over the loading and unloading of the assets. Textures can be packed together so when you request one texture, you "pre-load" other textures. It can be useful if you are customizing a given object and you want to quickly switch between the textures it can have.
More info: https://docs.unity3d.com/Packages/com.unity.addressables@1.9/manual/index.html
Unity advises against using the Resources
3.1. Best Practices for the Resources System
Don't use it.
In the time i posted this i researched a little bit, and i decided to use this, the problem is that the Documentation is not a really good and there isn't much info about ti, but im gonna try it.
Your answer
Follow this Question
Related Questions
into which folder can i import my jpeg files so i can put some texture on a wall obj? 0 Answers
Set texture / EnableKeyword not working in build 1 Answer
ridiculous load time using Resources.Load() on android build 0 Answers
Resources.LoadAllOfType With ScriptableObjects? 1 Answer
ScriptableObject , use Resources.Load sprite then it have error. 0 Answers