I created a small utility class that I have been missing a couple of times in Unity, especially when working on AR and VR projects lately. The Boolean3 class simply holds 3 boolean values and displays all of them in only one row in the Editor to save space.
Boolean3 comes in handy for example when you want to have a switch for each axis or direction. Also – like Vector3 – it is possible to iterate over a Boolean3, which can make code shorter and more readable:
Boolean3 debugPosition = new Boolean3(true, false, true);
for(int axis = 0; axis < 3; axis++) {
if(debugPosition[axis]) {
Debug.Log(axis + ": " + transform.position[axis]);
}
}
Instead of:
bool debugPositionX = true;
bool debugPositionY = false;
bool debugPositionZ = true;
if(debugPositionX) {
Debug.Log("0: " + transform.position.x);
}
if(debugPositionY) {
Debug.Log("1: " + transform.position.y);
}
if(debugPositionZ) {
Debug.Log("2: " + transform.position.z);
}
Imagine you are working on that code and you need to change the contents after the if statement several times. Without the Boolean3 you need to copy and paste every change to the other two if statements and adjust them accordingly. A lot of time wasting errors can happen here when you forget to change a parameter or variable name!
Here is the implementation:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Holds 3 Boolean values.
/// They can be accessed via [] operator as well,
/// e.g. boolean3[1] instead of boolean3.y.
/// </summary>
[System.Serializable]
public struct Boolean3 {
public bool x;
public bool y;
public bool z;
public Boolean3(bool all) {
this.x = all;
this.y = all;
this.z = all;
}
public Boolean3(bool x, bool y, bool z) {
this.x = x;
this.y = y;
this.z = z;
}
public bool this[int index] {
get {
switch(index) {
case 0:
return x;
case 1:
return y;
case 2:
return z;
default:
throw new System.IndexOutOfRangeException();
}
}
set {
switch(index) {
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
default:
throw new System.IndexOutOfRangeException();
}
}
}
public override string ToString() {
return "Boolean3(" + x + ", " + y + ", " + z + ")";
}
}
And the PropertyDrawer to show all of the values in one row:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
/// <summary>
/// Defines the Look of a <see cref="Boolean3"/> in the Unity Editor.
/// It makes sure the three values are shown in one single row instead of three.
/// </summary>
[CustomPropertyDrawer(typeof(Boolean3))]
public class Boolean3Drawer : PropertyDrawer {
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
EditorGUI.BeginProperty(position, label, property);
// Draw label
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
// Do not indent child fields
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
// Calculate rects
var rectWidth = position.width / 3f;
var xRect = new Rect(position.x + rectWidth * 0, position.y, rectWidth, position.height);
var yRect = new Rect(position.x + rectWidth * 1, position.y, rectWidth, position.height);
var zRect = new Rect(position.x + rectWidth * 2, position.y, rectWidth, position.height);
var x = property.FindPropertyRelative("x");
x.boolValue = EditorGUI.ToggleLeft(xRect, "X", x.boolValue);
var y = property.FindPropertyRelative("y");
y.boolValue = EditorGUI.ToggleLeft(yRect, "Y", y.boolValue);
var z = property.FindPropertyRelative("z");
z.boolValue = EditorGUI.ToggleLeft(zRect, "Z", z.boolValue);
// Set indent back to what it was
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
}
}
Make sure the Boolean3Drawer is saved to a folder named “Editor” since it is using the UnityEditor assembly. Or simply download the Unitypackage.
Feel free to copy and adjust the code to your needs. Please write a comment and tell me what you think or when there is something I could improve!