📜  raycast unity - C# (1)

📅  最后修改于: 2023-12-03 15:34:37.556000             🧑  作者: Mango

Raycast in Unity - C#

Raycasting is a powerful technique used in computer graphics, physics engines and game development that allows to determine the intersection point between a ray and a solid object. In Unity, raycasting is widely utilized for collision detection, character controllers, AI behaviors and more. In this article, we will explore how to implement raycasting in Unity using C#.

Basics of Raycasting

A ray in Unity is represented by a Ray or Raycast struct, which contains two properties: an origin (the starting point of the ray) and a direction (the vector in which the ray is projected). The simplest way to cast a ray is to use the Physics.Raycast method, which takes a Ray parameter and returns a boolean indicating whether the ray hit a collider or not.

Ray ray = new Ray(transform.position, transform.forward);
float maxDistance = 100f;
if (Physics.Raycast(ray, out RaycastHit hit, maxDistance))
{
    Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.green);
    // Do something with the hit object
}
else
{
    Debug.DrawRay(ray.origin, ray.direction * maxDistance, Color.red);
}

In this example, we create a ray starting from the current position of a game object and projecting it forward with a maximum distance of 100 units. If the ray hits a collider, we draw a green line from the origin to the point of intersection, and we can access the hit object through the RaycastHit parameter. Otherwise, we draw a red line indicating that the ray didn't hit anything.

Customizing Raycasting

While the Physics.Raycast method is convenient for quick collision detection, it has some limitations in terms of customization. For instance, we can't control the frequency or accuracy of the raycasting, or the types of colliders it interacts with. To overcome these limitations, we can use the Physics.RaycastAll method, which returns an array of all the hits detected by the ray, sorted by distance.

Ray ray = new Ray(transform.position, transform.forward);
float maxDistance = 100f;
int layerMask = LayerMask.GetMask("Default", "Obstacles");
RaycastHit[] hits = Physics.RaycastAll(ray, maxDistance, layerMask);
foreach (RaycastHit hit in hits)
{
    Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.green);
    // Do something with each hit object
}

In this example, we cast a ray with the same settings as before, but we also specify a layer mask that limits the interaction to two layers: the default layer and a custom "Obstacles" layer. This means that the ray will only detect colliders belonging to these layers, ignoring everything else. Then, we use a foreach loop to iterate over all the hits and draw a green line for each one.

Another way to customize raycasting is to use the Physics.RaycastNonAlloc method, which pre-allocates an array for the hits and fills it with the detected collisions, up to a maximum number. This can be more efficient than allocating a new array every time, especially if we expect to cast many rays per frame.

Ray ray = new Ray(transform.position, transform.forward);
float maxDistance = 100f;
int layerMask = LayerMask.GetMask("Default", "Obstacles");
RaycastHit[] hits = new RaycastHit[10];
int numHits = Physics.RaycastNonAlloc(ray, hits, maxDistance, layerMask);
for (int i = 0; i < numHits; i++)
{
    Debug.DrawRay(ray.origin, ray.direction * hits[i].distance, Color.green);
    // Do something with each hit object
}

In this example, we cast a ray with the same settings as before, but we also create a fixed-size array of 10 RaycastHits. Then, we call the Physics.RaycastNonAlloc method to fill the array with the detected collisions, up to a maximum distance of 100 units and only interacting with the two layers specified. Finally, we use a for loop to iterate over the actual number of hits and draw a green line for each one.

Conclusion

Raycasting is a fundamental technique in game development and Unity provides a variety of tools to customize and optimize it. By using the Physics.Raycast, Physics.RaycastAll and Physics.RaycastNonAlloc methods, we can detect collisions between rays and colliders, filter them by layers or tags, and efficiently process multiple hits in a single frame.