Boolean3 Utility Class for Unity

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.

How a Boolean3 looks in the Editor
Boolean3 in the Editor

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!

Download Boolean3 Unitypackage
Download Boolean3 Unitypackage

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.

Download Boolean3 Unitypackage.
Download Boolean3 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!

Published by

Chris

Christian Kauppert is CTO & Head of XR Engineering at MSM.digital AR / VR Labs. Before he worked as a freelance Unity developer and VFX compositor for over 9 years. He uses this blog to show and write about selected works. Occasionally Chris also writes about issues and solutions he stumbles upon while developing interactive experiences and XR applications.

Leave a Reply

Your email address will not be published. Required fields are marked *