Skip to content

A demonstration of how to use ScriptableObjects with Addressables in Unity, so as to avoid unexpected instances of your assets.

License

Notifications You must be signed in to change notification settings

njelly/addressables-scriptableobjects-test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

addressables-scriptableobjects-test

Note: the ScriptableEvents package I'm using is available here, however this problem has to do with the Unity engine itself, and will affect any project using both Addressables and ScriptableObjects.

Here's the problem...

If you're like me, you probably read this article or watched this Unite talk on architecting your Unity project using ScriptableObjects, and got excited about how you might use the patterns in your own project. You also like the idea of using Addressables to control your game's memory footprint. However, as you develop, you will notice ScriptableObjects loaded via Addressables behave differently on a build than they do in the editor. This can be very discouraging, as it was for me. If you do not understand the nuance from the start, you might waste days of work before finally making a build and see that none of those ScriptableObjects you were so excited about are working!

Lesson learned: test your project on your target platform early and often!

What's the solution?

In this project I demonstrate how to use a single built in scene to load your game content, so as to avoid unexpected instances of a ScriptableObject. I feel this solution remains true to goal of ScriptableObjects (an alternative to Singletons, highly decoupled logic, obvious and designer-friendly location of the game's state and data) while retaining the usefulness of Addressables (finer control over memory, more flexibility with Scenes in relation to memory).

Running this project in Unity, you will notice spawning cubes via AssetReference will increment the count in the editor, but not on a build. Spawning via direct prefab reference will work regardless. The way I've set this up is the first scene is a mandatory built-in Loader scene which prompts the user to load the next scene, which is either addressable or a built-in. Built-in scenes will not work as expected, and this is not fixable. However, the addressable scene will work if and only if the ScriptableObjects in that scene are also addressable.

In the built-in scene, two instances of the ScriptableObject exist: one in the scene itself and the other with the assets loaded via Addressables. This can be verified by comparing the values of Object.GetInstanceID. In the addressable scene, because the scene, the prefabs, and the ScriptableObject are loaded along side each other, there is just one instance of the ScriptableObject and all references point to that instance!

In Editor (expected behavior):

Recording.2023-05-30.222809.mp4

On Build (built-in scene, unexpected behavior):

screen-20230530-215349.2.mp4

On Build (addressable scene, partially fixed!)

The red counter references a ScriptableObject that is marked as addressable, the orange counter does not. The orange counter and the addressable prefab have separate instances of the ScriptableObject! The red counter's setup therefore demonstrates a viable workaround for using ScriptableObjects and Addressables.

screen-20230531-215650.2.mp4

Project Architecture Implications

The best practice when working with Addressables is to ensure that your project has exactly one built-in scene, and that scene's only job is to load (via Addressables!) the next scene that actually contains your games content. This ensures you are always working with the expected instances of your ScriptableObject assets.

While developing in the editor, it is not as important to be strict on how your assets and scenes are loaded and in what order, since the editor will always reference the same instance of your ScriptableObjects. This is good news for developers working on teams, since the typical Unity workflow stays exactly the same while editing scenes and prefabs. However at build time, it is a requirement that the game loads through the initial built-in scene. Hopefully, these requirements are flexible enough for large, professional projects.

About

A demonstration of how to use ScriptableObjects with Addressables in Unity, so as to avoid unexpected instances of your assets.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published