Shared Values
Shared Values are individual variables wrapped in a ScriptableObject. They can be used to represent one value shared between several GameObjects or other ScriptableObjects.
The project already includes Shared Values of different types, like int, float, Boolean, Vector3, Vector2, Quaternion, string, and Color; but you can create custom types by extending the base class (see below).
Sample usages 💡
If you have a lot of prefabs that draw debug gizmos in the scene, a Shared Value can be used in place of a boolean to centralise that debug setting. Instead of having to turn individual Prefab's values on/off, you can now do it from a centralised place.
Another example can be to express some stats related to a character with Shared Values: both the player character and the UI can reference the player's health. When the character gets damage or heals itself, the UI immediately reacts to that.
Using Shared Values
Creating a new Shared Value
To create a Shared Value, simply position your mouse in the Project View and right click, then Create > ScriptableObject Tools > Shared Values, and then choose the type you want to create.
Referencing a Shared Value in scripts
To reference the Shared Value SO, simply declare a variable of its type, like usual:
If visualised in the inspector, you should see the field appear and display its value.
Accessing/writing the value
To use the value contained in a Shared Value SO, all you need to do is reference it and access its .Value
property, like so:
Alternatively, you can use the SO reference directly to access its value, which will be cast to its inside type:
However, assignment and other operators like +
, +=
, -
, -=
etc. can't be used on the SO directly, but need to be used on its .Value
property:
To manipulate the data in it, you just add, assign, subtract etc. to its .Value
property:
The 'AllowIndirectEditing' property
When a Shared Value SO is referenced in a script, it shows its contained property in the Inspector of the script that is referencing it. Using AllowIndirectEditing
one can decide whether this value is editable from these Inspectors, or whether to protect it from unwanted edits.
It is off by default, to suggest a workflow where the user of a Shared Value SO has to intentionally go to the SO and edit the value there, reinforcing the idea that they are editing an external value that might be used by other scripts too.
It has no effect at runtime.
Extending Shared Values
Adding a new Shared Value type
To create a new Shared Value class holding a different type, all you need to do is to create a new C-sharp file, and in it, subclass SharedValueBase<T>
like this (we'll use Vector4
as an example):
Don't forget to include the [CreateAssetMenu]
attribute at the top, so you can create a new ScriptableObject using the right-click menu.
Giving it a custom PropertyDrawer
With this, the value is ready to use, however, it won't display using a custom PropertyDrawer like all the others. Using a custom PropertyDrawer is absolutely not needed, but it's a nice thing that can improve usability.
To create one: create a new script in an Editor
folder, and put something like this in it:
The important thing is that you specify which class you are providing a PropertyDrawer for (in this case, SharedVector4
), and in the GetFieldMaxWidth()
method, provide the space you want the property to take when visualised inside a referencing MonoBehaviour or ScriptableObject. This will really depend on the type you are embedding.
Note: This pre-made PropertyDrawer will only work for one-value types. For other types like structs and complex classes, you might have to write a PropertyDrawer from scratch.
For more information on this, refer to the Unity API Reference for PropertyDrawers.
Last updated