Some time ago I made this very little plugin, which allows to easily drag & drop in the inspector assets without causing them to be loaded in memory by Unity when the scene loads. Maybe there’s already something like that somewhere, but I just couldn’t find anything. I have decided to make it open source in case somebody finds it useful, or wants to test it, improve something, etc.:
As you may know, when you drop an asset to some object’s slot in the inspector, when the scene is loaded the asset (and all assets to which it has references, specially in the case of prefabs) will be loaded in memory automatically. It’s not a problem if the assets are small or are going to be used immediately, but for big assets, or many of them, that won’t be needed until later in the game, it’s an issue, since they will use a big chunk of memory even if they are not used.
The solution is to not use direct references to those assets, put them inside a Resources folder (so that Unity includes them in builds even if not directly referenced), and use “Resources.Load” to load them using a path. But this is not very convenient, you’d need to be careful when moving or renaming the assets to make sure to modify the paths used to load them, and of course you miss the nice drag & drop functionality in the inspector.
What this little plugin does is just that, allows you to directly drop in the inspector the assets that are in a Resources folder, plus allows you to move and rename them without having to keep track of anything (with a limitation explained in the readme file), while still avoiding Unity loading the asset in memory until you decide to do so.
Edit: now it’s possible to use assets that aren’t inside a Resources folder, with the help of the new class “DelayedAssetProxy”. Basically, a “DelayedAssetProxy” acts as a wrapper to hold the original assets; the “DelayedAssetProxy” must itself be inside a Resources folder, but the original asset can be anywhere.
The usage is explained in the readme file, but basically you’d use the type “DelayedAsset” for fields, instead of the normal asset type:
[SerializeField] DelayedAsset thing;
[SerializeField] DelayedAsset[] manyThings;
You can restrict the type of assets that are allowed on that slot by using the attribute “DelayedAssetType”:
[SerializeField] [DelayedAssetType(typeof(GameObject))] DelayedAsset gameObjectReference;
[DelayedAssetType(typeof(Material))] public DelayedAsset materialReference;
Edit: now those slots will also allow assigning a “DelayedAssetProxy” which holds an asset of the desired type.
And to load the original asset you have to use the “Load” method, and “Unload” to unload it from memory:
[SerializeField] [DelayedAssetType(typeof(Transform))] DelayedAsset transformReference;
void Awake()
{
// Load the original asset:
Transform transf = (Transform)transformReference.Load();
if (transf != null)
{
// If existing, add an instance to the scene:
Instantiate(transf.gameObject);
// Unload the original asset if desired:
transformReference.Unload();
}
}