unity c# raycast hit
Usar capas y máscara de bits con Raycast en Unity (1)
La mayoría de Raycast
preguntas de Raycast
que veo usan la Layermask
incorrectamente. Aunque les funciona por suerte, generalmente se topan con problemas cuando realmente quieren excluir un GameObject de Raycast
.
Esta respuesta está hecha para cubrir todos los escenarios en los que una persona desearía usar la Capa para filtrar GameObjects al realizar el raycast.
1. ¿ Cómo haces ray-out en un GameObject particular que está en una capa llamada "cubo"?
Primero usa LayerMask.NameToLayer("cube")
para convertir el nombre de la capa a número de capa. La función LayerMask.NameToLayer
devuelve -1
si la capa no existe. Debe verificar esto antes de realizar cualquier operación bit a bit de capa.
Raycast a una capa en particular (solo "cubo"):
//Convert Layer Name to Layer Number
int cubeLayerIndex = LayerMask.NameToLayer("cube");
//Check if layer is valid
if (cubeLayerIndex == -1)
{
Debug.LogError("Layer Does not exist");
}
else
{
//Calculate layermask to Raycast to. (Raycast to "cube" layer only)
int layerMask = (1 << cubeLayerIndex);
Vector3 fwd = transform.TransformDirection(Vector3.forward);
//Raycast with that layer mask
if (Physics.Raycast(transform.position, fwd, 10, layerMask))
{
}
}
La parte más importante del ejemplo anterior es int layerMask = (1 << cubeLayerIndex);
.
Para abreviar esta respuesta, no revisaré los errores del resto de la respuesta.
2. ¿ Qué pasa si tienes 10 GameObjects en la escena pero solo quieres raycast a solo 2 GameObjects e ignoras el resto? ¿Cómo haces eso?
Digamos que las capas de ese objeto son "cubo" y "esfera".
Raycast a las capas "cubo" y "esfera" e ignore el resto:
//Convert Layer Name to Layer Number
int cubeLayerIndex = LayerMask.NameToLayer("cube");
int sphereLayerIndex = LayerMask.NameToLayer("sphere");
//Calculate layermask to Raycast to. (Raycast to "cube" && "sphere" layers only)
int layerMask = (1 << cubeLayerIndex) | (1 << sphereLayerIndex);
3. ¿ Qué sucede si quieres retransmitir a todos los GameObjects pero ignorar 1?
Digamos que GameObject para ignorar está en la capa "cubo".
Raycast a todos, pero ignora la capa de "cubo":
//Convert Layer Name to Layer Number
int cubeLayerIndex = LayerMask.NameToLayer("cube");
//Calculate layermask to Raycast to. (Ignore "cube" layer)
int layerMask = (1 << cubeLayerIndex);
//Invert to ignore it
layerMask = ~layerMask;
4. ¿ Qué sucede si quieres emitir rayos a todos los GameObjects, pero ignorar 2 (múltiples) GameObjects?
Nuevamente, las capas a ignorar son las capas "cubo" y "esfera".
Raycast para casi ignorar las capas de "cubo" y "esfera":
//Convert Layer Name to Layer Number
int cubeLayerIndex = LayerMask.NameToLayer("cube");
int sphereLayerIndex = LayerMask.NameToLayer("sphere");
//Calculate layermask to Raycast to. (Ignore "cube" && "sphere" layers)
int layerMask = ~((1 << cubeLayerIndex) | (1 << sphereLayerIndex));
O
//Convert Layer Name to Layer Number
int cubeLayerIndex = LayerMask.NameToLayer("cube");
int sphereLayerIndex = LayerMask.NameToLayer("sphere");
//Calculate layermask to Raycast to. (Ignore "cube" && "sphere" layers)
int layerMask = (1 << cubeLayerIndex);
layerMask |= (1 << sphereLayerIndex);
layerMask |= (1 << otherLayerToIgnore1);
layerMask |= (1 << otherLayerToIgnore2);
layerMask |= (1 << otherLayerToIgnore3);
//Invert to ignore it
layerMask = ~layerMask;
Finalmente, si conoce el índice / número de la capa, no es necesario utilizar la función LayerMask.NameToLayer
. Solo inserte ese índice de capa allí. Por ejemplo, vamos a ray-out a la capa "cubo" que está en el índice n . ° 9 . Usted podría simplemente hacer int layerMask = (1 << 9);
.
Consulte el manual de Capas para leer más sobre este objeto.
Las funciones de Raycast de Unity tienen un parámetro que puedes usar para emitir rayos a un GameObject en particular. También puede usar ese parámetro para ignorar GameObject en particular.
Por ejemplo, la función de Raycast:
public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
El parámetro layerMask
se usa para especificar qué objetos deben / no deberían recibir el raycast.
1. ¿ Cómo haces ray-out en un GameObject particular que está en una capa llamada "cubo"?
2. ¿ Qué pasa si tienes 10 GameObjects en la escena pero solo quieres raycast a solo 2 GameObjects e ignoras el resto? ¿Cómo haces eso?
Digamos que las capas de ese objeto son "cubo" y "esfera".
3. ¿ Qué sucede si quieres retransmitir a todos los GameObjects pero ignorar 1?
Digamos que GameObject para ignorar está en la capa "cubo".
4. ¿ Qué sucede si quieres emitir rayos a todos los GameObjects, pero ignorar 2 (múltiples) GameObjects?
Nuevamente, las capas a ignorar son las capas "cubo" y "esfera".