What is Addressables?
The Addressable Asset System provides an easy way to load/unload assets from memory based on an “address.” It simplifies asset management by making it easier to create and distribute content packages, reducing the complexity of managing assets.
Addressables use asynchronous loading to support loading from anywhere with any collection of dependencies. Whether you use direct references, traditional asset bundles, or the Resources folder, Addressables offers a simpler way to make your game more dynamic.
Why Shouldn’t the Object.Instantiate() System Be Used?
The Instantiate
method is an old-school feature that has remained unchanged since Unity was first published. Essentially, all of our Prefabs and Objects must be stored in Unity’s Assets folder within the Resources folder.
Everything stored in the Resources folder (Textures, 3D models, Shaders, Audio, TextAssets, JSON files, ScriptableObjects, etc.) is allocated and loaded into memory as soon as the Unity project is built and the application is started on the device.
For example, let’s assume our game has 50 different scenes:
- The assets and models used for these 50 scenes will vary. Our characters, materials, textures, etc. Almost all of these assets have the potential to take up megabytes of space.
- Having the entire game loaded in the background while the user is in a single scene is a suicide mission for mobile platforms.
- To prevent this, various manipulations exist, such as serialization, asset bundles, etc., but none offer practicality and simplicity in application.
Considering the reasons mentioned above and our frequently discussed project constraints, I don’t think we have any option other than using Unity’s Addressables system.
The concept of Addressables is simple; unlike the Instantiation system, it has only .Load() and .UnLoad() features.
We will have an additional step to load the asset into memory before instantiating it into our scene. Similarly, we will need to UnLoad our destroyed assets from memory. (Even if we don’t UnLoad, Unity’s infrastructure allows the Garbage Collector to handle this for us.)
Let’s Look at the Code Differences:
Standard Resources or Object.Instantiate System
private async void CreateProjectile()
{
// Instantiate projectile
Rigidbody clone;
clone = Instantiate(projectile, transform.position, transform.rotation);
// Give it velocity.
clone.velocity = transform.TransformDirection(Vector3.forward * 10);
// Wait for 2 seconds.
await UniTask.Delay(2000);
// Destroy it after 2 seconds.
Destroy(clone.gameObject);
}
Every time the CreateProjectile()
command is called in our scene, memory allocation will occur, and this allocation won’t be cleaned up until the scene is destroyed.
Optimization with Addressables
private async void CreateProjectile()
{
// Load the asset into memory and wait asynchronously.
var reference = await Addressables.LoadAssetAsync<Rigidbody>("prefabKey");
// Instantiate projectile
Rigidbody clone = Instantiate(reference.Result);
// Give it velocity.
clone.velocity = transform.TransformDirection(Vector3.forward * 10);
// Wait for 2 seconds.
await UniTask.Delay(2000);
// Destroy it after 2 seconds and clean it from memory.
Addressables.ReleaseAsset(reference);
}
💡 For stress tests, check out this video:
https://www.youtube.com/watch?v=uNpBS0LPhaU
Reply by Email