Whats the reason we are limited to 1 layer per object?

A while ago I asked for a workaround for the limit of 1 layer per object

Basically, instead of having WorldStatic and WorldDynamic layers, why not have a World, Static, and Dynamic layer and then just assign 2 layers, the World and Static layer, to world objects that dont move.
Another example, instead of a PlayerTeamRed, PlayerTeamBlue, ObjectTeamRed, ObjectTeamBlue, why not just Player, Object, TeamRed, TeamBlue and assign multiple layers?
I didnt really get any workaround…

I have hit this issue again and am curious as to why we are limited to 1 layer per object in the first place?

To my understanding, the layer is just a bitmask, so layer 1 is like 000…0001, layer 2 is like 000…0010, etc…
When you do a raycast, you pass a layermask to have the raycast detect (or place ~ in front of the layermask to have it ignore).
So lets say the object is set to layer 2, and the raycast layermask is set to layer 1.
By using the binary operation (objectLayer & layerMask) we can check if the layerMask contains the objectLayer.
What that binary operation does is set the result bits to 1 in the spots that both masks have a 1.

Example 1-
objectLayer = 000…0010 (layer 2)
layerMask = 000…0001 (layer 1)
result = 000…0000

Result is false

Example 2-
objectLayer = 000…0010 (layer 2)
layerMask = 010…0010 (layer 2)
result = 000…0010

Result is true

The equation (objectLayer & layerMask) is true even if there is just 1 resulting bit matching.
If we want to require all resulting bits to match the layerMask, we can do
-return ((objectLayer & layerMask) == layerMask).

If we want to require all resulting bits to match the objectLayer, do
-return ((objectLayer & layerMask) == objectLayer).

And I guess if you want to check if the resulting bits match both the objectLayer and layerMask, so they are exactly the same, you would do
-result = (objectLayer & layerMask);
-return (result == objectLayer && result == layerMask).

Now lets assume unity allowed us to have multiple layers on a single object.
So now we set our object to be layer 1 and layer 2.
Lets say we want our raycast to detect any object that contains layer 2.
We would have a method like so
Raycast(raycastData…, layerMask, Mask.RequireAny)

Example 1-
objectLayer = 000…0011 (layer 1 and layer 2)
layerMask = 000…0001 (layer 1)
result = 000…0001

The result is true since we just wanted to detect if any of the resulting bits matched.

If we want to require all resulting bits to match the layerMask, we can do
Raycast(raycastData…, layerMask, Mask.RequireAllLayerMask)

Example 1-
objectLayer = 000…0011 (layer 1 and layer 2)
layerMask = 000…1001 (layer 1 and layer 4)
result = 000…0001

Result is false since there was only 1 resulting bit match with the layerMask

Example 2-
objectLayer = 000…1011 (layer 1, layer 2 and layer 4)
layerMask = 000…1001 (layer 1 and layer 4)
result = 000…1001

The result is true since all resulting bits match with the layerMask.

Then you can have Raycast(raycastData…, layerMask, Mask.RequireBothExact), etc…

So everything seems like it would work fine with having multiple layers on a single object, but maybe there is a reason I am not seeing that we have such a limitation?

You could post a feature request.

In the meantime, you might be able to work a similar system on top of the current engine. I imagine you could make a CollisionMaskManager and attach a CollisionMask script to all of your objects. Your CollisionMask is just going to hold the mask you’ve laid out in your post. When the scene first loads, the Manager will find all objects with that behavior and manually iterate all objects to ignore all other objects that it needs to via Physics.IgnoreCollision

If you need to update an object’s mask during runtime, you need only tell the Manager to update that single object’s relation with other objects.

Mind you, there are some limitations with this approach, but it seems feasible.

Good luck! Let me know if you try it and how it turned out. :slight_smile:

[EDIT]
No, I don’t have an answer to your actual question. :stuck_out_tongue: Maybe one of the nice Unity pros trolling around will stop by. Sadly, I do not know them by name for an @ :frowning:

I checked before making this thread and someone seems to have already made one
https://feedback.unity3d.com/suggestions/multiple-layers-on-one-object
Though, even if they do eventually add this, I dont think it would be any time soon so I am not really here expecting this to be added, more so just curious why it is as it is. Although, I think they are upgrading to a new version of physx, so maybe they can add this in the new update.

Ye, I thought of having it so I have a component that I can choose all the layers I want to be on this object, then assign the objects to some static collection somewhere so that when I raycast I can grab from the collection all the objects I want to cast against based on their layers and the raycast layermask, temporarily change their layer to a canCast layer while everything else is on a ignoreRaycast layer, blah blah blah. However, I dont know the performance of changing an objects layer, and depending on how many casts I do and how many objects there are in the scene, things might get slow.

Overall, not expecting a change, just curious as to why its like this in the first place.

What’s interesting is that the layer approach Unity uses, is really close to the simple example of how to filter that nvidia gives in it’s api. And then mentions it’s probably too simple for a complex game:)

My guess is that if they improve this, it would most likely be a new api instead of just allowing more layers per object. Something closer to the nvidia api so if you need it, you can get much more fine grained control, but at a cost in complexity.

1 Like