Raycasting a specific square area

I’m currently trying to experiment how to do different game types, so I started with the RTS genre. I’ve got the Select a Single Unit down, with a raycast to the collider of the Unit. But what I need is the way of doing a Square raycast, or something similliar to that, so I can make 2 points, one from MouseButtonDown and Up.

I’ve tried Physics.OverlapSphere, but this isn’t a square area, but rather a Sphere with radius which isn’t working in an RTS.

I’m not asking for an super duper solution, i’m just asking how I would go about doing this, since no functions in the Unity API exists for this.

I’m assuming, by “square raycast”, you’re talking about selecting multiple units with a square lasso-tool? If so, the trick is to not use raycasting. :slight_smile: The easiest way is to work solely in screen space. For each of your units, convert their positions to screen space like this:

    Vector3 screenSpacePos = yourCamera.WorldToScreenPoint(yourUnitsTransform.position);

This vector contains the unit’s screen (pixel) position in the x and y coordinates. The z coordinate is the unit’s depth (distance) from the camera, and is not needed for this.

Record 2 points with the mouse. You have to update the second point in real-time! The first point is where the user started his click, the second point is whatever position the mouse is at in the subsequent frames after the first click:

    // Record this when the user first clicks:
    Vector3 firstPoint = Vector3.zero;
    if(Input.GetMouseButtonDown(0))
        firstPoint = Input.mousePosition;

    // Then record this every frame while the user has the button held down:
    Vector3 secondPoint = Vector3.zero;
    if(Input.GetMouseButton(0))
        secondPoint = Input.mousePosition;

Using these two points, form a rectangle (Rect) and test the unit’s screen space position against this Rect using its .Contains method:

    // Every frame, use those two vertices to form a rectangle:
    Rect screenRectAngle = new Rect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y);

    // Test your unit's screen space position against this rectangle to see if the rectangle contains the point:
    if(screenRectAngle.Contains(screenSpacePos))
        // Your unit is hereby selected...

If Rect.Contains returns true, it’s because the unit’s screen space position is within the rectangle formed by the mouse during dragging, and the unit should therefore be selected.

Please note that the code above is not presented as a working solution. It is untested and will likely fail if used as is. For example, it completely disregards all the care that must be taken to form the rectangle correctly, if the user moves the mouse’s second point behind and/or above the first instead of in front and down. The code sample is intended just to provide an illustration on the approach.

Feel free to ask follow-up questions in the comments. :slight_smile: