Hi,
I write a lot of scripts like this:
public class MyScript : MonoBehaviour
{
public Transform VeryImportantReference;
private void Start()
{
if (VeryImportantReference == null)
{
Debug.LogError("VeryImportantReference not set.");
enabled = false // avoid log spam
}
}
private void Update()
{
// use the reference here...
}
}
Is there a best practice of this scenario or even a RequireField attribute like RequireComponent. This checks are very repetitive and annoying…
No, there isn’t one.
You can make one.
Easiest way is to just write an ‘assert’ function:
public static class Assert
{
public static bool ReferenceExists(UnityEngine.Object obj, string name)
{
if(obj == null)
{
Debug.LogError(name + " not set");
return false;
}
else
{
return true;
}
}
}
public class MyScript : MonoBehaviour
{
public Transform VeryImportantReference;
void Start()
{
this.enabled = Assert.ReferenceExists(VeryImportantReference, "VeryImportantReference");
}
}
Unity has its own Assert class so you don’t even have to write your own
1 Like
New in 5 I think. Not sure which minor version.
Nice, that goes in the right direction. Maybe I can create something, that gives a visual feedback in the editor, like a (Property xyz not set warning)… A attribute or something like that.
system
April 26, 2016, 7:52am
7
You can also do that in the OnValidate MonoBehaviour message to make sure your references are assigned at edit time instead of doing in Start.
I’ve created a simple attribute and property drawer:
Attribute:
public class RequiredAttribute : PropertyAttribute
{
}
Drawer:
[CustomPropertyDrawer(typeof(RequiredAttribute))]
public class RequiredDrawer : PropertyDrawer
{
private const float HELPBOX_HEIGHT = 38.0f;
private const float TOP_MARGIN = 2.0f;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
float propHeight = EditorGUI.GetPropertyHeight(property, label);
position.height = propHeight;
EditorGUI.PropertyField(position, property, label);
if (property.objectReferenceValue == null)
{
position.y += position.height + TOP_MARGIN;
position.height = HELPBOX_HEIGHT;
EditorGUI.HelpBox(position, string.Format("{0} is required!", label.text), MessageType.Error);
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float height = EditorGUI.GetPropertyHeight(property, label);
if (property.objectReferenceValue == null)
{
height += HELPBOX_HEIGHT + TOP_MARGIN;
}
return height;
}
}
Now, you will get an error in the inspector, if the property with the require attribute has a null reference.
This isn’t perfect because if you collapse the component, there will be no reminder, that you have to set this property before you should press play.
2 Likes