7 February 2022

Unity 3D Game Architecture with Scriptable Variables Objects

There is a great Unity 3D Game Architecture talk from Ryan Hipple from a Unity talks in Austin 2017 called Unite Austin 2017. Game Architecture with Scriptable Objects. the talk is available in Youtube at Unite Austin 2017 – Game Architecture with Scriptable Objects. I’ve implemented my own version of the modular and variable data as talked in minute 15. 

The idea is reduce global states and ability to share piece of data between components and prefabs. 

In this instance we want to avoid having a singleton, a single centralized reference for all variables. While this sounds convenient this introduces unnecessary dependencies. You don’t want to test and check bits of codes, or characters or element of the game without having to bring the whole lot of  references from various systems and sub-systems. 

While you can define a collection of fields and properties within a specific scriptable object. But to get the most extensibility and modularity this particular implementation breaks it down to the most granular data elements. Int, float, string vector2, vector3, bool. 

The base objects are called scriptable object variables. 

The object needs to be available via the asset creation context menu, so easy for any designer to create a new variable. 

Let’s go through the base class, the whole package is available on my public GitHub repository at https://github.com/GuillaumeLecouteux/UnityData 

This is serializable. We want to asset to persist, there is a serialization callback receiver to ensure the value get set to its initial value during the application startup. I’ve embedded some comments in this chunk of code.  

[Serializable] 
    public abstract class AVariable<T> : ScriptableObject, ISerializationCallbackReceiver 
    { 
// the initial value 
        [SerializeField] private T _initialValue; 

// the runtime property to be consumed, updated or read by any other component 
        public T Value 
        { 
            get => _value; 
            set => SetValue(value); 
        } 

// a callback action to notify any subscriber of a change of value 
        public event Action<T> VariableChange; 

 // the actual value, only visible internally 
        [HideInInspector] 
        [SerializeField] 
        protected T _value = default(T); 

 // the setter, the main purpose being to catch and report changes  
        public virtual void SetValue(T newValue) 
        { 
            if (newValue != null && !_value.Equals(newValue)) 
            { 
                _value = newValue; 
                VariableChange?.Invoke(_value); 
            } 
        } 

 // setting the initial value, this is for edit prurpose, not to be used in game 
        public void SetInitialValue(T newInitialValue) 
        { 
            _initialValue = newInitialValue; 

        } 

 // setting the value from another variable object 
        public void SetValue(AVariable<T> value) 
        { 
            Value = value.GetValue(); 
        } 

 // getting the value 
        public T GetValue() 
        { 
            return Value; 

        } 

 // resetting to initial value 
        public void Reset() 
        { 
            SetValue(_initialValue); 
        } 

 // deserialization happening during startup 
        public void OnAfterDeserialize() 
        { 
            _value = _initialValue; 
        } 

        public void OnBeforeSerialize() { } 

// standard C# class function 
        public override string ToString() 
        { 
            return _value.ToString(); 
        } 

// standard C# class function 
public override int GetHashCode() 
        { 
            return _value.GetHashCode(); 
        } 
    }
SHARE:
Development 0 Replies to “Unity 3D Game Architecture with Scriptable Variables Objects”