Skip to content

Instantly share code, notes, and snippets.

@adamski11
Last active March 20, 2023 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save adamski11/00b3e0e8e4be520d7336765ef6843e9d to your computer and use it in GitHub Desktop.
Save adamski11/00b3e0e8e4be520d7336765ef6843e9d to your computer and use it in GitHub Desktop.
A ComponentVariable<T> can be used as a mini dependancy injection system to allow for rapid prototyping and the referencing of values without having to hard set those references in your scripts.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.Serialization;
/*To use this script, when you need to get a variable from another script/component, instead of directly
referencing the component and then the specific variable (e.g. rBody.velocity), you would make a "ComponentVariable"
of the specific variable type that you need (e.g. ComponentVariable<Vector3>). You would then pass the compenent
reference and the code name of the variable into the ComponentVariable in the inspector.
For example, to access to the Vector3 variable "velocity" in a Rigidbody component instead of having to create
a "public Rigidbody rBody" and then call "rBody.velocity", you would create a "public ComponentVariable<Vector3> _velocityVal",
and then in the inspector you'd set the "_componentReference" to be the Rigidbody component and the "_variableName" to be
"velocity" (the code name of the variable), which would then allow you to get the velocity value by calling "_velocityVal.Value",
assuming everything is named correctly.*/
[System.Serializable]
public class ComponentVariable<T> {
[SerializeField] Component _componentReference;
[SerializeField] string _variableName;
private MemberInfo _variableMemberInfo;
private MemberTypes _variableMemberType = MemberTypes.All;
public T Value {
get {
//If we haven't already grabbed the member info
if (_variableMemberInfo == null) {
//Check we have a component to look in
if (_componentReference == null) {
Debug.LogError("No component selected!");
return default(T);
}
else {
System.Type componentType = _componentReference.GetType();
//First, check if it is a property
PropertyInfo property = componentType.GetProperty(_variableName);
//If it is, store the reference and note it is a property
if (property != null) {
_variableMemberType = MemberTypes.Property;
_variableMemberInfo = property;
}
//Otherwise, check if it is a field
else {
//If it is, store the reference and note it is a field
FieldInfo field = componentType.GetField(_variableName);
if (field != null) {
_variableMemberType = MemberTypes.Field;
_variableMemberInfo = field;
}
else {
//Otherwise we can't find the variable
Debug.LogError($"Named variable {_variableName} canont be found as a field or a property. Please check and try again.");
}
}
}
}
//Once we have a cached _variableMemberInfo, just return the correct value based on the type
return GetReflectedPropertyValue();
}
}
private T GetReflectedPropertyValue() {
switch (_variableMemberInfo) {
case PropertyInfo pInfo:
return (T)pInfo.GetValue(_componentReference);
case FieldInfo fInfo:
return (T)fInfo.GetValue(_componentReference);
}
return default(T);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment