Scriptable objects are incredibly useful. For some reason they seemed daunting but having used them on my last couple of projects they have instantly become a key part of my workflow when using middleware with Unity.
What is a Scriptable Object?
Put simply, a scriptable object is a used to store data. This is then saved in your assets folder and can be added to and referenced by scripts. Using a scriptable object is a more memory efficient solution to storing data that would otherwise be stored in a prefab.
How to Create a Scriptable Object
To be able to create instances of scriptable objects you first need to define what data any particular object will store.
In your “Assets” folder create a new script and give it a name – for this example I’ll call it “SFXEvent.cs”.
Open it up and change it to inherit from “ScriptableObject” instead of “MonoBehaviour”. As scriptable objects are saved as individual assets, it is really usefull to define where to find it in your “Create Asset” menu the option for creating this scriptable object can be found. To do this add the following immediately above where you class is named :
[CreateAssetMenu(fileName = “SFXEventDefault”, menuName = “ScriptableObjects/SFXEvent”, order = 1)]
Your script should now look like this :
Next it is time to define what data this will hold. But first it is probably useful to know why we are doing this…
Why are they useful when implementing middleware?
As a sound designer working in middleware we are able to define all sorts of parameters both in Unity and in middleware. In an ideal world we can just set a lot of the parameters in FMOD/Wwise and forget about them, then call triggers from inside Unity. But sometimes a developer may not know how to use audio middleware and it’s associated methods that are used to trigger audio events.
For instance, some dev’s may not have done much audio implementation work before, so the subtle differences of when to play an event as a one shot. By using a scriptable object, we define not only the FMOD/Wwise event that is associated to it, but also what play back methods should be used when calling it. This allows the dev to simply call a Play function and the scriptable object will be referenced to decide how to play the correct event in the correct way.
All a little theoretical at the moment, but I’ll run through an example and it should make a bit more sense.
Adding some data to a Scriptable Object
Inside our scriptable object let’s add a couple of bits of data that will be useful. For this example let’s use FMOD. Make sure then to add “Using FMODUnity” at the top of the script.
- A string called “Key” – used to “search” for a specific SFXEvent. This will the name such as “Footstep” or “CollectStar”
- A string called “FmodEventPath” with “[EventRef]” immediatly above it. This is the path of the FMOD event that I want to call.
- A bool called “isOneShot” for setting whether to trigger as a one shot.
- A bool called “is3D” to set the event as a 3D sound.
- A bool called “isAttachedToGameObject” to set if the sound event is to be attached to a game object as an emitter.
The script should now look a little like this :
Now I’ve got the scriptable object, I can now create some instances. To do this, go to your Project tab, right click > Create > ScriptableObject > SFXEvent.
I’ve created 3 of SFXEvent assets :
If you click on one, the inspector will then show your fields and I have set them up with some appropriate values for each field :
(Very) Basic Audio Manager
Writing the script for a basic audio manager is out of the scope of this post but showing how to reference a scriptable object and how to use it would be useful.
In addition to the above you could add a “Find SFX Event” method that requires a string input. This method would search through a list of SFXEvents and return one that has a matching “key” to the input of the function. This means that you can easily hard code something such as a UI sound by simply passing a the required “key” from code to another method in our audio manager that will perform the the “Find SFX Event” method before calling the above example play method.
As I said before, scriptable objects can store any number and type of data, even other scriptable objects, which is very useful for grouping assets together for a very simple way for dev’s to reassign audio events without needing to dig into a middleware project for a very simple change.