UnityVR–Component 4–Ray/Raycast/Linecast/OverlapSphere

Directory

Introduction to Ray/Raycast/Linecast//OverlapSphere

Ray class

Physics.Raycast method

Application 1: Realize mouse click to emit rays and detect objects

Application 2: Implement mouse click and drag objects

Physics.Linecast and Physics.OverlapSphere

Application 3: Trigger attack when entering range


Introduction to Ray/Raycast/Linecast//OverlapSphere

Ray (Ray class) is an infinitely long line emitted from a point in one direction in a three-dimensional world. Its main applications are, for example:

1. In the previous article unity oculus handle ray, use the ray emitted from the handle to click the UI button in VR;

2. In ordinary 3D games, use the mouse or touch to drag and click objects (build a ray from the screen to the object);

3. Miscellaneous: Sights in the shot, drawing a range from an object, etc…

Raycast is a method in the physics system, which uses the form of rays to detect whether there is a collision body on the way the rays pass, just like the laser door damage game that was done before. The same type is RaycastAll

Linecast and OverlapSphere are linear detection and spherical detection in the physical system, detecting whether there is a collision body in the linear or spherical range, Linecast returns a Boolean value, and OverlapSphere returns an array .

Ray class

The two important parameters of a ray are origin and direction. The parameterized structure of the Ray class is public Ray(Vector3 origin, Vector3 direction), that is, we need to pass two parameters, the starting point and the direction, when creating a ray. In addition, there is only one method GetPoint() in this class, which is used to return a point on a ray. The method is defined as follows:

public Ray(Vector3 origin, Vector3 direction)
        {
            m_Origin = origin;
            m_Direction = direction.normalized;
        }

public Vector3 GetPoint(float distance)
        {
            return m_Origin + m_Direction * distance;
        }

Physics.Raycast method

Function: Launch a ray in the scene and check whether it collides with the collider.

Definition: (There are actually 15 overloads) The syntax is as follows

public static bool Raycast(Ray ray)

public static bool Raycast(Vector3 origin, Vector3 direction)

public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance)

//Used in laser gate:
public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask)

Important parameter description:

parameter function
origin Ray starting point coordinates (world), Vector3
direction ray direction, Vector3
distance ray length, float
layermask The selected detection layer (other layers are not detected), int
hitInfo The first object information detected, RaycastHit class

The hitInfo parameter is the RaycastHit class, which is used to store the information of the first detected object, including: transform, rigidbody, collider, distance (the distance from the starting point of the ray to the intersection point with the colliding object ), point (the coordinates of the intersection point), normal (the normal vector of the ray entering the plane)

Physics. Line

Application 1: Realize mouse click to emit rays and detect objects

In the application, we often have the need to click and pick up objects with the mouse or handle, then we need to send a ray from the position of the screen (that is, Camera) or the handle to the object. The following is set to capture the click of the left mouse button, and emit a ray from the main camera, the direction is the position of the mouse click, and then use RaycastHit to detect whether the enemy is shot (the enemy is added to the Enemy layer). The code in update() is as follows:

Update()
{
  if(Input. GetMouseButtonDown(0))
  {//If there is a click on the left mouse button
     //Define a ray ray, set the ray from the main camera to the mouse position
     Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);
     Tools.DrawLine(transform, ray.origin, ray.direction, Color.white, 0.05f);//Use the DrawLine method in the Tools tool to draw this line
     //Test Raycast
     Physics.Raycast(ray, out RaycastHit hit, 100, LayerMask.GetMask("Enemy","UI"));
     if(hit. collider != null)
     {
       Debug.LogError("Hit the enemy!");
     }
  }
}

The effect is as shown in the figure below. You can see that every time the ray points to a red enemy, there will be a text prompt in the lower left corner.

Application 2: Realize mouse click and drag objects

Implementation process:

Step 1: Make a ray from Camera to the mouse click direction (same as application 1);

Step 2: ray detection of the dragged object; modify the above Update()

private Transform clicked; //The object clicked by the mouse
void Update()
    {
        if(Input. GetMouseButtonDown(0))
        {//Click the left mouse button to generate a ray
            //Test Ray, set the ray from the main camera to the mouse position
            ray=Camera.main.ScreenPointToRay(Input.mousePosition);
            Physics.Raycast(ray, out RaycastHit hit, 100, LayerMask.GetMask("object"));
            //Check the object layer here
            if(hit. collider != null)
            {
                clicked = hit.transform; //The object detected by the ray is dragged by the mouse
            }
        }
        if(Input. GetMouseButton(0))
        {//If the left mouse button is continuously clicked, drag the object
            if(clicked!= null)
            {
                Vector3 pos=Tools.MouseToWorld(clicked.position);//The method of the third step
                clicked.position=new Vector3(pos.x,clicked.position.y,pos.z);
                //The height of the object (y) remains unchanged
            }
        }
        if(Input. GetMouseButtonUp(0))
        {//If the left mouse button is lifted, release the object
            clicked = null;
        }
    }

Step 3: If the left mouse button is detected to be continuously clicked, the mouse position is converted into a three-dimensional space position and assigned to the object;

*Note: Application 2 focuses on mouse position conversion. The click position of the mouse is a two-dimensional screen position, which needs to be converted into a three-dimensional space position. This is a conversion that needs to be used frequently. You can put this method into Tools .cs tool set. The following is the conversion code, which seems to be very complicated to turn around. You can refer to the implementation of the ScreenToWorldpoint API of Unity Camera to understand the principle.

 //Add a mouse coordinate conversion tool to the Tools tool set
    //Convert the two-dimensional coordinates clicked by the mouse on the screen to three-dimensional coordinates in space
    public static Vector3 MouseToWorld(Vector3 target)
    {//Need to pass in the position of a clicked object, because the coordinates of the mouse originally only have XY, no Z axis
        //Convert the target's world coordinates to screen coordinates
        Vector3 targetScreen=Camera.main.WorldToScreenPoint(target);
        // Add the XY position of the mouse on the screen to the z position of the target to get the screen position of the mouse
        Vector3 curseScreenPos=new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreen.z);
        //Finally convert the mouse screen position to the world position
        Vector3 curseWorldPos=Camera.main.ScreenToWorldPoint(curseScreenPos);
        return curseWorldPos;
    }

The effect is as follows:

Physics.Linecast and Physics.OverlapSphere

Both APIs detect colliders in a linear or spherical range. Linecast can be used in shooting games, and OverlapSphere has been used in small game tank battles before. Their syntax is as follows:

//linear detection
public static bool Linecast(Vector3 start, Vector3 end, out RaycastHit hitInfo)

public static bool Linecast(Vector3 start, Vector3 end, int layerMask)

//Spherical detection, returns an array listing all detected colliders
public static Collider[] OverlapSphere(Vector3 position, float radius)

public static Collider[] OverlapSphere(Vector3 position, float radius, int layerMask)

App 3: Trigger attack when entering range

Simply make a “tank battle” effect similar to what you have done before. Create a new script OverlapSphere.cs hanging on the protagonist Hero

public class OverlapSphere : MonoBehaviour
{
    private Collider[] colliders;
    private GameObject bullet;

    void Update()
    {
        colliders=Physics.OverlapSphere(transform.position, 2, LayerMask.GetMask("Enemy"));
        //Set the center, radius, detection layer
        foreach(var collider in colliders)
        {
            bullet = Resload.Instance.LoadPrefab("Bullet");//load bullet
            bullet.transform.position = transform.position;
            bullet.transform.LookAt(collider.transform);
        }
    }
}

The effect is as follows: