informa
3 MIN READ
Featured Blog

Unity3D Culling Mask Tip

Changing the layers displayed by a Unity3D camera requires some bitfield maths. This post provides a more explicit and readable way to handle this functionality.

This post was first published on the Concealed Intent blog

Recently I was working on making layers appear and disappear programmatically in Unity3D. The Unity Camera class has a culling mask such that each camera can be set to only display a subset of the available layers. This is handy for placing 3D objects in one layer visible by the main camera, and say the GUI in another layer visible by a different camera. This can be setup using the camera's culling mask dropdown in the editor. However, I wanted to be able to change the visible layers during runtime in response to a player's actions (in Concealed Intent pressing a key will make a grid appear or disappear over the playing area).

To change the culling mask programmatically some bitfield maths is required. Each layer is represented by a bit in an integer. Layer 12 is 000000000000000000100000000000 - the twelfth bit in a 32-bit integer mask. The culling mask itself is just the combination (bitwise OR) of these layers. Thus, if the culling mask is 000000000010000000100000001000 (equivalent to the number 526344), the 4th, 12th and 20th layers would be displayed, as the 4th, 12th and 20th bits are turned on. To do this in code, first find the number of the layer and then shift a bit this number of places, then add or remove this from the mask. For example, to add the "Enemy" layer to the mask would be: cam.cullingMask |= 1 << LayerMask.NameToLayer("Enemy"). Other bitwise operations can remove layers.

I find this messy. I prefer my code to be a little more explicit and readable. So I wrote a set of class extensions for the Camera to add a better way of manipulating the culling mask. Just add the class below into your project and then cam.LayerCullingShow("Enemy") will add the "Enemy" layer to the camera "cam". Similarly, cam.LayerCullingHide("Enemy") will remove the layer; cam.LayerCullingIncludes("Enemy") will tell you whether it is being displayed or not; and cam.LayerCullingToggle("Enemy") will flip the visibility of the "Enemy" layer. If preferred, the layer mask can be passed as a parameter rather than the layer's name. Enjoy.

using UnityEngine;
public static class CameraExtensions {
    public static void LayerCullingShow(this Camera cam, int layerMask) {
        cam.cullingMask |= layerMask;
    }
    public static void LayerCullingShow(this Camera cam, string layer) {
        LayerCullingShow(cam, 1 << LayerMask.NameToLayer(layer));
    }
    public static void LayerCullingHide(this Camera cam, int layerMask) {
        cam.cullingMask &= ~layerMask;
    }
    public static void LayerCullingHide(this Camera cam, string layer) {
        LayerCullingHide(cam, 1 << LayerMask.NameToLayer(layer));
    }
    public static void LayerCullingToggle(this Camera cam, int layerMask) {
        cam.cullingMask ^= layerMask;
    }
    public static void LayerCullingToggle(this Camera cam, string layer) {
        LayerCullingToggle(cam, 1 << LayerMask.NameToLayer(layer));
    }
    public static bool LayerCullingIncludes(this Camera cam, int layerMask) {
        return (cam.cullingMask & layerMask) > 0;
    }
    public static bool LayerCullingIncludes(this Camera cam, string layer) {
        return LayerCullingIncludes(cam, 1 << LayerMask.NameToLayer(layer));
    }
    public static void LayerCullingToggle(this Camera cam, int layerMask, bool isOn) {
        bool included = LayerCullingIncludes(cam, layerMask);
        if (isOn && !included) {
            LayerCullingShow(cam, layerMask);
        } else if (!isOn && included) {
            LayerCullingHide(cam, layerMask);
        }
    }
    public static void LayerCullingToggle(this Camera cam, string layer, bool isOn) {
        LayerCullingToggle(cam, 1 << LayerMask.NameToLayer(layer), isOn);
    }
}

Contact Details:

 

Latest Jobs

Manticore Games

San Mateo, California
8.23.22
Senior Software Engineer - Mobile

Sony PlayStation

San Diego, California
6.23.22
Sr. Online Programmer

The Walt Disney Company

Glendale, California
8.1.22
Associate Marketing Manager - Walt Disney Games

Insomniac Games

Burbank, California
8.26.22
Accessibility Design Researcher
More Jobs   

CONNECT WITH US

Explore the
Subscribe to
Follow us

Game Developer Job Board

Game Developer Newsletter

@gamedevdotcom

Explore the

Game Developer Job Board

Browse open positions across the game industry or recruit new talent for your studio

Browse
Subscribe to

Game Developer Newsletter

Get daily Game Developer top stories every morning straight into your inbox

Subscribe
Follow us

@gamedevdotcom

Follow us @gamedevdotcom to stay up-to-date with the latest news & insider information about events & more