Raycasting Question - [SOLVED]

Hello!

Ive got a question regarding raycasting and if it is possible to only raycast towards one object?

I made a simple picture to show how things are lined up:

Or in unity:

So they are using the layermask correctly to see the enemies , but when 1 wants to attack 4 - then 1 thinks that there is no Line of sight becouse the Raycast is intercepted by 3.

Code:

    public virtual bool CheckLOS(Unit ThisUnit , Unit Enemy)
    {
        RaycastHit hit;
        Vector3 dir = Enemy.transform.position - ThisUnit.transform.position;
        int layer = 0;
        if (ThisUnit.Team == 21) { layer = 22; }
        if (ThisUnit.Team == 22) { layer = 21; }
        int layermask = 1 << layer;
        int walllayer = 10;
        int walllayermask = 1 << walllayer;
        int finallayer = layermask | walllayermask;

        if (Physics.Raycast(ThisUnit.transform.position, dir, out hit, 5f, finallayer))
        {
            if(hit.collider.transform==Enemy.transform)
            {
                return true;
            }
        }
            return false;
    }

Is there any way to check line of sight that ignores all colliders/layers besides the target.

-Tobias

There’s a lot of flavors of raycast… you can actually raycast directly against a specific collider, which ignores everything else.

Raycasting, colliders, planes, Plane, etc:

And there is also EventSystem.RaycastAll for raycasting in the UI / EventSystems context.

Raycasting in 2D:

Hey Kurt , thanks for replying so fast.

The collider.raycast seems to be what i am looking for , but it seems that this causes the units to see through layer 10 (Walls) - and is always treated as being in line of sight.

9419138--1319771--upload_2023-10-19_18-38-58.png

Might need a few raycasts…

First do a regular old raycast in the direction of the guy you want, but set layers to only pick up WALLS.

For this first raycast you are only looking to find a point where you hit a wall.

From this point you can compute the distance of how far your ray can go before it hits a wall.

Now raycast at the target you want:

  • is the impact point farther than the first raycast distance? Then you can’t hit it.

  • if the impact point is closer, then yeah, you can hit it.

Hey Kurt , that seems to have done the trick thanks alot!

Cant believe i didnt think about using several raycasts - sometimes you really need another pair of eyes on the code.

The code that worked for anyone else that has this problem in the future:

    public virtual bool CheckLOS(Unit ThisUnit , Unit Enemy)
    {
        RaycastHit hit;
        Vector3 dir = Enemy.transform.position - ThisUnit.transform.position;
        int walllayer = 10;
        int walllayermask = 1 << walllayer;

        float dist=Vector3.Distance(ThisUnit.transform.position, Enemy.transform.position);

        if (Physics.Raycast(ThisUnit.transform.position, dir, out hit, dist, walllayermask))
        {
           return false;
        }
        else
        {
            Ray ray = new Ray(ThisUnit.transform.position, dir);
            if (Enemy.collider.Raycast(ray, out hit, 5f))
            {
                return true;
            }
        }

        return false;
    }
1 Like

Awesome… you’re welcome!!

Doing multiple raycasts is actually pretty common, and Unity is a beast: raycasts are computationally fairly cheap, at least in most physics setups.

For instance, one application is to tell what percent of a given target is obscured, such as for “cover and concealment” kinda games like XCOM.

You can accomplish this by raycasting to multiple points on the target: head, chest, arms, legs, etc. Or you could even just raycast to X points from top to bottom of the target, or even left / right in a box around the player.

If you can hit them with 100% of the raycasts then you know they are not in cover.

In my Jetpack Kurt Space Flight game I even do them stochastically (randomly) to detect small objects beneath your craft to warn you about uneven ground: every frame I raycast three different random rays for 1 meter below the ship, and if any one of them differs in length from the others by more than 0.25m then I consider it uneven ground and activate a beeping warning system. I can even detect tiny little posts like landing lights within a few moments of them coming underneath your ship.

https://www.youtube.com/watch?v=34wbtTIWdDQ

That is a great thing to learn. I was handling raycasts like Getcomponents and distance calculations.
After i get this up and running i will have to run through my code again and see if i can improve/switch to the other raycast types.

Thanks again. Ive got work ahead of me after this :slight_smile:

1 Like