Jorge Vallejo Blog

Blog del creativo, ilustrador y profesor de videojuegos Jorge Vallejo

Unity: ¿Cómo se usan los LayerMask?

Cuando estamos usando Raycast ya sean 3D o 2D enseguida nos surge un problema común y es que ,para detectar un elemento con Raycast este tiene que tener Collider ¿como puedo hacer para que me detecte unos si y otros no?, sin tener que quitar dicho Collider, la solución son los LayerMask.
El problema es que el concepto es algo complicado por lo que he decidido crear este post tratando de explicarlo de mejor forma posible.
Primero hay que echarle un vistazo a los Layers, cualquier elemento en Unity puede estar colocado en un Layer y como vemos Unity se reserva para el 8 y nos deja los demás para nosotros, pero hay algo curioso, hay 32 layers posibles, ¿Por que exactamente 32? pues por que Unity untiliza un int 32 para controlar los layers, , es decir un numero con la forma 0000 0000 0000 0000 0000 0000 0000 0000 , donde cada bit representa si detecta o no, así el primero a la derecha corresponde al layer Default y el último seria nuestro layer 32.
¿Como creo un LayerMask para que detecte sólo un layer?
Primero creamos un LayerMask que es un int y asociamos 1 al bit que corresponde a ese Layer seria 1<< (Operador de desplazamiento a la izquierda) int del Layer
int mascara=1<<0;
O podemos recoger el indice del layer con LayerMask.NameToLayer(“Nombre del Layer”)

int mascara=1<<0;

Ahora la mascara será 0000 0000 0000 0000 0000 0000 0000 0001

Podemos visualizar el int con
print(System.Convert.ToString(mascara,2));
Segundo asociamos la mascara al Raycast, en este ejemplo usaremos un Raycasthit2D pero funciona igual para 3D

Ray2D rayo=new Ray2D(transform.position,Vector2.right); 
int mascara=1<<LayerMask.NameToLayer ("Default") ; 

El resultado: el Raycast sólo detecta los Collider que tengan Default

Muchas veces nos vamos a encontrar exactamente con el problema inverso, es decir, queremos que nuestro Raycast detecte todos los layers excepto uno, por ejemplo el del Player.
El camino a seguir seria muy parecido, creo la mascara , le digo que detecte solo a Player

int mascara=1<<LayerMask.NameToLayer ("Player")  ;

Y despues la invierto con ~ (Ascii 126) Información sobre el operador aqui

mascara=~mascara;

Ahora la mascara seria 1111 1111 1111 1111 1111 1110 1111 1111
Y el resto del código seria igual quedando

Ray2D rayo=new Ray2D(transform.position,Vector2.right); 
int mascara=1<<LayerMask.NameToLayer ("Player ")  ;
mascara=~mascara;
RaycastHit2D hit =Physics2D.Raycast (rayo.origin, rayo.direction,200,mascara); 

Al principio los LayerMask pueden resultar algo confusos por lo que aconsejo hacer pruebas tirando un Raycast con dos elementos con Layers diferentes para comprobar su funcionamiento.

Leave a Reply

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