@drgrandayy / @CodeSmile:
I can think of lots of reasons I might want to this, and I’ve solved this exact problem several times in the past which is why I’ve asked and answered the question here.
Today’s specific use case: I have a single projectile prefab which I want to use in 2 separate object pools one for player and one for enemy projectiles.
For various reasons I want to keep the pooled projectiles for the player on a different collision layer from the pooled projectiles of the enemy; and since both projectile pools use the same prefab, I can’t set the layer in the prefab.
To handle this I have a projectile pool monobehaviour which exposes “projectile collision layer” as an editor property.
When I clone the prefab in the projectile pool manager I set GameObject.layer for all GameObject instances in the projectile prefab to match the appropriate layer as defined in the the projectile manager properties.
The simplest way to allow the user to set the collision layer in a way which has nice UX in the editor is to use a LayerMask as a property; but obviously the LayerMask value for a layer is (2^layer) so you can’t use it to set GameObject.layer - hence the question / solution I posted.
Sure I could have used an int for this property but then I would have had to either manually check the layer number in the editor UI every time you wanted to set it or to visually check which layer it was, or maybe write a property drawer for something which really doesn’t need to be one.
Similarly, I could have used a string but that suffers from almost all the same issues as well as the fact it’s very easy to make a typo in a string (or, again, write a property drawer).
Using the extension method I posted above for LayerMask have relatively nice editor UX for the property with basically no code written.
Also, fwiw returning -1 in the case where multiple bits are set is 100% intentional - it says so in the comment, and the sample code below that shows you why - you can’t convert a LayerMask with more than 1 bit set in it to a value which can be used to GameObject.layer to a valid layer number; and if you try to then a Unity assert will tell you that the value is out of range.