You can add members to your scripts such as a StringReference, FloatReference or ColorReference. In the Inspector, you can set a simple constant value for them, as you would do normally. However, a toggle button allows you to switch it to 'Variable', changing it into an empty reference field.
You can then drag & drop any ScriptableObject or MonoBehaviour that implements the IValue<T> interface, where T is the type you need, into that reference field. Usually, you would create some assets in your project that provide these values. There are a few benefits to this functionality:
You can have many different scripts reference the same variable, so you only have to change the variable at one place in your project.
There are many variations of variables, each with unique behaviour to how they return a value.
For example, you can reference a StringVariable to simply get the string set within, or instead you can reference a StringCollectionVariable, which returns a random string from its collection.
This feature wouldn't be possible without the InterfaceReference script, found in the UtilityCollection module.
Normally, if you need an Inspector set value for your game, you would write something like this:
public string characterName;
To allow you to choose between a constant and a reference, you need to use a ValueReference instead. If you are using Unity 2020 or later, you can keep it simple for yourself and write:
public ValueReference<String> characterName;
If instead you are using a version of Unity older than 2020, you need to use wrappers that have already implemented the type parameter. This is because generic type serialization is not yet supported for the Unity 2019 and older Inspector GUI's (except for List<T>).
public StringReference characterName;
Either way, you now have a member field in the Inspector with a toggle button allowing you to choose between a constant value, or a variable. You can now drag & drop any object that implements the IValue<String> interface, returning that value for use by your script.
Note that the Constant field can also be a reference field, in case of a default Unity asset such as a Material or GameObject.
The following ValueReference types are available:
AcceleratedSettingsReference
ColorReference
FloatReference
GameObjectReference
IntReference
MaterialReference
QuaternionReference
SpriteReference
StringReference
Vector2Reference
Vector3Reference
You can create your own, just take a look in their scripts. It's pretty simple, as they all use the base class ValueReference.
Ofcourse, in Unity 2020 or newer, you wouldn't need this list at all. But if you are creating a plugin, you might want to support older Unity versions.
IValue<T> is the interface for anything that can return a value of the specified type. It can be implemented multiple times, so that a script can potentially return many different types of values.
For example:
public class ObjectWithNames : ScriptableObject, IValue<String>, IValue<List<String>>
To make things easier, there are 3 types of ScriptableObjects that implement IValue:
ValueVariable<T>. Returns a single value set in the inspector.
CollectionVariable<T>. Contains a list of values.
RandomValues<T>. Contains a minimum and maximum value.
The ValueVariable<T> class is the base class for any ScriptableObject exposing a single value. You can create your own easily, for whatever object type you need to be referenceable.
These are generally used for types that are not already a referenceable asset within the Unity project hierarchy.
ColorVariable
FloatVariable
IntVariable
StringVariable
The CollectionVariable<T> class is the base class for any ScriptableObject exposing a list of values. It returns either a random value from the list, or the entire list.
It acts both as an IValue<T> and an IValue<List<T>>.
ColorCollectionVariable
FloatCollectionVariable
GameObjectCollectionVariable
IntCollectionVariable
MaterialCollectionVariable
SpriteCollectionVariable
StringCollectionVariable
There are a few ScriptableObjects which return a random value when the value is requested. You can set a minimum and maximum value, and any value between those two is returned randomly.
If you want random selection from a list instead, use the CollectionVariables.
RandomColorVariable
RandomFloatVariable
RandomIntVariable
MonoBehaviour scripts can also implement the IValue interface. There is one example present in the module:
TransformValues, returns a Vector3 or Quaternion value. The returned value can be the position, eulerAngles or scale, either local or global.
Note that in order to drag & drop a reference, you need to drop the actual MonoBehaviour script instance on the object, not the object itself!