I’ve had a disagreement with a co-worker for quite a while now about using Resources.load(). Now, I understand how it is used, but I’m trying to get some points on why/when/where to use it. Currently, my co-worker prefers sticking just about everything under the Resources directory. Then loading it during run-time using Resources.load (of course). From my perspective, this is a misuse of the tool.
Can anybody help me understand the implications of using Resources.load better?
This is what I understand:
Used for loading assets that are
rarely used so that they are not
loaded as part of any of the scenes. " For example, there may be a character or other object that can appear in any scene of the game but which will only be used infrequently (this might be a “secret” feature, an error message or a highscore alert, say). ", says Unity.
If you want WebPlayers to load a game quickly then you can make a lightweight scene that loads only the minimum required assets, then use Resources.load as needed to load the remaining assets.
I agree with your points - well put. If you put it all in Resource directories then it will be included in the build - no matter if you stop using it - normally only assets that are actually being used in a built scene will be included in the actual executable. So putting everything in Resources is a bit of a nightmare because you have to work out whether you are still using things or your executable starts to fill with wasted stuff - big problem on phones.
I use resources for things like:
Music - because the player can select a track and I don’t want them hanging around when they aren’t being used
Character animations because I want to load the set that are relevant for the currently selected character.
Images that may be displayed at some point during any scene (like control tips etc).
Your first point - things that may be loaded but aren’t always - like characters that may only be used sometimes.
Prefabs that are always needed in a scene but have no obvious “home” get stuck in a game object that loads with the scene (set using the inspector into public variables- then it is a compile error if I spell it wrong). Generically useful prefabs get loaded in a singleton UsefulPrefabs script where the prefabs are set using the inspector so that I don’t have to hunt around in code for them by name (this script is DontDestroyOnLoad and is always included by loading additively from a master scene if it isn’t found).
I would much prefer to be able to identify where my objects are so that there is no hunting in code looking for the names being passed to Resources.Load - and as mentioned above - strings are fragile compared to variables.
I generally agree with your coworker, but it depends on your game’s needs. (EDIT: Actually, I don’t agree that EVERYTHING should go in Resources – I kind of misread the question. I put all prefabs, audio files, and certain large GUI textures, NOT dependencies like models, animations, textures, etc.) My game is not web-based, so bundling all assets into the build is not a problem. I put most prefabs in Resources because many times objects I want to load are not instantiated in the scene such as bullets, randomized enemies, random objects, etc. I had been instantiating all my objects from a master prefabs object that contained links to all the prefabs in my game, but as you can imagine it started taking up a silly amount of memory as the game grew. I ended up switching to a string-based solution (created with an editor script from my prefabs object each time I change something) which allows me to load the assets as needed from disk with Resources.Load. I use id’s to look up prefabs from the lists, but you could also use enums, so there’s no dealing with strings in the code. I personally think its far more trouble to manage a prefab list of exactly what objects you want loaded on a per-scene basis because you have to be constantly cleaning up this list for every scene every time you want to add or remove something.
(When adding new objects to my lists,
I add them to the giant prefab list on
disk and then run an editor script
which updates the string list.)
Could you give some more info on this system you use?
I was thinking of keeping a class with static strings of resource paths.
The editor script you described sounds much more convenient.
class MyResources
{
static string
player = "Prefabs/Player",
bullet = "Prefabs/Bullet",
themeSong = "Audio/Main Theme"
;
}
//anywhere i need a resource
Instantiate(Resources.Load(MyResources.player));
I know this is an old thread. But Unity will automatically put the stuff in your project that have dependency links into your project folder, like textures or objects that are in a scene.
So really put as little as you need into the Resources folder (to keep the build size down). Only put stuff you will need to load during the game.Like GUIs, sounds, GameObjects that you need to instantiate or use.
If you already have a link to it, like using a GameManager Object with some scripts, then it will get put into the build, so it doesn’t matter if it’s in the Resources folder or not. But it does make it easier to clean up and change stuff if it’s not in the Resources Folder.
You can also look at using Asset Bundles and loading from there if your project is large.