-
-
Save TheLouisHong/ba27e2921c01e7b92fdc457e6613b20f to your computer and use it in GitHub Desktop.
Unity generic scriptable object variable reference pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
/// <summary> | |
/// Reference Class. | |
/// </summary> | |
[Serializable] | |
public abstract class Reference | |
{ | |
} | |
/// <summary> | |
/// Reference Class. | |
/// </summary> | |
[Serializable] | |
public class Reference<T, G> : Reference where G : Variable<T> | |
{ | |
public bool UseConstant = true; | |
public T ConstantValue; | |
public G Variable; | |
public Reference() { } | |
public Reference(T value) | |
{ | |
UseConstant = true; | |
ConstantValue = value; | |
} | |
public T Value | |
{ | |
get { return UseConstant ? ConstantValue : Variable.Value; } | |
} | |
public static implicit operator T(Reference<T, G> Reference) | |
{ | |
return Reference.Value; | |
} | |
public static implicit operator Reference<T, G>(T Value) | |
{ | |
return new Reference<T, G>(Value); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEditor; | |
using UnityEngine; | |
/// <summary> | |
/// ReferenceDrawer Class. | |
/// </summary> | |
[CustomPropertyDrawer(typeof(Reference), true)] | |
public class ReferenceDrawer : PropertyDrawer | |
{ | |
/// <summary> | |
/// Options to display in the popup to select constant or variable. | |
/// </summary> | |
private readonly string[] _PopupOption = { "Use Constant", "Use Variable" }; | |
/// <summary> Cached style to use to draw the popup button. </summary> | |
private GUIStyle _PopupStyle; | |
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |
{ | |
if (_PopupStyle == null) | |
{ | |
_PopupStyle = new GUIStyle(GUI.skin.GetStyle("PaneOptions")); | |
_PopupStyle.imagePosition = ImagePosition.ImageOnly; | |
} | |
label = EditorGUI.BeginProperty(position, label, property); | |
position = EditorGUI.PrefixLabel(position, label); | |
EditorGUI.BeginChangeCheck(); | |
// Get properties | |
SerializedProperty useConstant = property.FindPropertyRelative("UseConstant"); | |
SerializedProperty constantValue = property.FindPropertyRelative("ConstantValue"); | |
SerializedProperty variable = property.FindPropertyRelative("Variable"); | |
// Calculate rect for configuration button | |
Rect buttonRect = new Rect(position); | |
buttonRect.yMin += _PopupStyle.margin.top; | |
buttonRect.width = _PopupStyle.fixedWidth + _PopupStyle.margin.right; | |
position.xMin = buttonRect.xMax; | |
// Store old indent level and set it to 0, the PrefixLabel takes care of it | |
int indent = EditorGUI.indentLevel; | |
EditorGUI.indentLevel = 0; | |
int result = EditorGUI.Popup(buttonRect, useConstant.boolValue ? 0 : 1, _PopupOption, _PopupStyle); | |
useConstant.boolValue = result == 0; | |
EditorGUI.PropertyField(position, useConstant.boolValue ? constantValue : variable, GUIContent.none); | |
if (EditorGUI.EndChangeCheck()) | |
property.serializedObject.ApplyModifiedProperties(); | |
EditorGUI.indentLevel = indent; | |
EditorGUI.EndProperty(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
/// <summary> | |
/// StringReference Class. | |
/// </summary> | |
[Serializable] | |
public class StringReference : Reference<string, StringVariable> | |
{ | |
public StringReference(string Value) : base(Value) { } | |
public StringReference() { } | |
} | |
/// <summary> | |
/// StringVariable Class. | |
/// </summary> | |
[CreateAssetMenu] | |
public class StringVariable : Variable<string> { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
/// <summary> | |
/// Variable Class. | |
/// </summary> | |
public class Variable<T> : ScriptableObject | |
{ | |
public T Value; | |
public void SetValue(T value) | |
{ | |
Value = value; | |
} | |
public void SetValue(Variable<T> value) | |
{ | |
Value = value.Value; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
/// <summary> | |
/// Vector3Reference Class. | |
/// </summary> | |
[Serializable] | |
public class Vector3Reference : Reference<Vector3, Vector3Variable> | |
{ | |
public Vector3Reference(Vector3 Value) : base(Value) { } | |
public Vector3Reference() { } | |
} | |
/// <summary> | |
/// Vector3Variable Class. | |
/// </summary> | |
[CreateAssetMenu] | |
public class Vector3Variable : Variable<Vector3> { } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment