- Home /
Require inspector assignment?
Was wondering if there was a way to require a variable be assigned via inspector, ala RequireComponent. I'm sure this has been asked plenty of times before, but all searches of Google and UA returned results about NullReferenceExceptions people were seeing because they forgot to assign something via inspector (which is exactly what I'm trying to prevent). I'm writing code that'll be used by others, including non-technical folks, so leaving a comment like
// this var is assigned via inspector
doesn't help much.
What do you want to happen if the inspector variable isn't assigned?
You can say. If that var is null, secretly assign it to something so they won't notice it >:D.
But seriously if it is going to be used by others, then you atleast expect them to know the unity interface. They dont need to know code. Only how to change a public variable in the inspector.
But.. If it was not assigned you can call a Debug.LogError("Assign the var pls");
this will pauze unity.
The same thing as RequireComponent, don't let the user play or build until it's resolved
This is actually a really common use case. There are workflows with prefabs where previously assigned references would get unassigned by accident, and we wouldn't know until at some point in runtime where we would get the NullReferenceException on first use. This is unclear and problematic. I was expecting something like [RequireAssignedReference] attribute.
Answer by InfernoZYB · Jul 27, 2015 at 12:19 AM
You could do Hexers answer but if its not assign make it so the launcher stops playing.
public GameObject ABC;
if(ABC != null){
//Line of code
}
else
{
Debug.LogError("assign the gameobject ABC in the inspector before resuming");
UnityEditor.EditorApplication.isPlaying = false;
}
Hmm this does seem like pretty much exactly what I'm looking for, though I wish there was a more elegant solution built into Unity but this works. Thanks!
I am late to the game, but even your answer is not good enough.
In latest Unity version you can do as followed:
// Tell the Assert class to throw something on failure.
UnityEngine.Assertions.Assert.raiseExceptions = true;
// And check your fields.
UnityEngine.Assertions.Assert.IsNotNull(variable, "$$anonymous$$ember \"variable\" is required.");
Answer by Gru · Mar 27, 2018 at 03:45 PM
EDIT: Unity now knows to report the correct error in the Console, but does not stop play mode.
Your best bet would be to use the bailer idiom.
Extension method for convenience:
public static partial class GameObject_ExtensionMethods {
public static void UnassignedReference(this GameObject go, string referenceName) {
Debug.LogError("Unassigned Inspector reference: " + referenceName, go);
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#endif
}
}
You must guard the last line, otherwise the project will not compile in Build.
private void Start() {
if(myVar == null) gameObject.UnassignedReference(nameof(myVar));
// Normal Start Stuff...
}
It is better to do these checks once in Start or Awake and proceed as normal than indent the code every time before use (bailer). The problem with this solution is the code will continue to run for the rest of Starts or Awakes, even though we set the isPlaying to false, and this will most probably cause other NullReferenceExceptions down the line, which could confuse the user.
Answer by Hexer · Jul 27, 2015 at 12:02 AM
public GameObject ABC;
if(ABC != null){
//Line of code
}
else
{
Debug.LogError("assign the gameobject ABC in the inspector before resuming")
}
This code will pauze unity if ABC were to be null.
Or do :
If(ABC){
//line of code
}
else
{
Debug.LogError("assign the gameobject ABC in the inspector before resuming")
}
Either of one should work.
This is just checking if the variable is null, not emulating the behavior of RequireComponent
"This is just checking if the variable is null, not emulating the behavior of RequireComponent"
RequireComponent makes it so that there HAS to be a component attached to the gameobject the script is on. http://docs.unity3d.com/ScriptReference/RequireComponent.html
But i think i know what you are trying to get at.
Yes exactly, I'm asking about emulating that same behavior for inspector assignments
Answer by undereyes · Mar 15, 2017 at 08:36 PM
Hi @murkantilism, my response comes a little late, but I just saw this, I'm sorry. You have a way to make this much more comfortable and automatic.
After the end of your Class add this code:
[CustomEditor(typeof(*YOURCLASSNAME*), true)]
public class *YOURCLASSNAME*Inspector : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
*YOURCLASSNAME* myClass = (*YOURCLASSNAME*)target;
if (myClass.yourVariable == null) myClass.yourVariable = yourValue;
}
}
Replace YOURCLASSNAME with your Class Name and yourVariable/yourValue with your variable/value.
If I understand this correctly, what this does is set the inspector variable to some default, "yourValue", if it's not assigned via the inspector. The original objective was to prevent the user from entering Play mode or running a build if there was a missing inspector assignment, just like RequireComponent does for components, rather than automatically applying a band-aid.
Yes, you have understood correctly. Sorry for the answer, I misunderstood it, too many hours working.
Haha no worries, thanks anyway for thoughts!
Answer by Develax · Jun 01, 2019 at 05:15 PM
The helper class:
using UnityEngine;
internal static class MyDebug
{
public static void Assert<T>(T variable) where T : class
{
Debug.AssertFormat(variable != null, "The instance of '{0}' is `null`.", typeof(T).Name);
}
}
The usage:
public class Entity : MonoBehaviour
{
public ExplosionDamage Damage;
private void Awake()
{
MyDebug.Assert(Damage); // will print "The instance of 'ExplosionDamage ' is `null`."
}
}