Raycast for player recognition

Hi Guys!
Trying to implement a turret, that turns a canon in the direction of the player if he is in sight.
The turning works pretty good, also I'm using a rotation limit based of the local position of the whole turret stub and it works fine. The only problem is, that the turret keeps firing when the player is behind a wall.
I'm raycasting towards the player with a radius of SightRadius, if the ray hits a layer defined in LayerMask, it should return true and I also test if the object hit has a tag of value "Player".
5990930--644390--Turret.jpg
I guess I'm using the Racast-Method the wrong way or have I slight misunderstanding?
Maybe someone has any additional suggestions to help a Unity-Noob? :smile:
Anyway, here's a part of my code:

    public override void move()
    {
        // Get player position relative to enemy position
        Vector3 dirToTarget = (mTargetHitPoint.position - transform.position);
        RaycastHit hit;
        if (Physics.Raycast(transform.position, dirToTarget.normalized, out hit, mSightRadius, playerMask))
        {
            Debug.DrawRay(transform.position, dirToTarget * hit.distance, Color.yellow);           
            if (hit.collider.gameObject.tag == "Player")
            {
                mPlayerInSight = true;
            }
        }
        else
        {
            mPlayerInSight = false;
        }

        if (mPlayerInSight)
        {

            // Bring world coordinates to local coordinates
            Vector3 inverse = transform.InverseTransformDirection(dirToTarget);
            // Get angle in Degree between both points
            float rotation = Mathf.Atan2(inverse.y, inverse.x) * Mathf.Rad2Deg;
            // If Player in sight, shoot him
            // Clamp rotation
            if (rotation > -aimingAngleLocal && rotation < aimingAngleLocal)
            {
                setCanon(rotation);
                shoot();
            }
        }
    }

Your else, which sets mPlayerInSight to false, belongs to the if-statement with the raycast itself. So the only condition in which you set mPlayerInSight to false is when the ray does not hit anything. Otherwise you either do nothing, or set it to true. So it's probably true from either seeing the player before, or because that's its default state, or something like that. The problem should not occur anymore if you add an else mPlayerInSight = false after line 12 in the example.

1 Like

Thanks, was kinda code blind to not see that.
But it seems this was not the problem though, this code:

if (Physics.Raycast(transform.position, dirToTarget.normalized, out hit, mSightRadius, playerMask))
        {
            Debug.DrawRay(transform.position, dirToTarget * hit.distance, Color.yellow);
            if (hit.collider.gameObject.tag == "Player")
            {
                mPlayerInSight = true;
            }
            else
            {
                mPlayerInSight = false;
            }

        }
        else
        {
            mPlayerInSight = false;
        }

Shows same results :-/
Object between turret and player has a mesh, mesh renderer and a box collider, does it need more to collide with the ray?

Use some Debug.Log()s to see if everything works as expected. Or rather, where it doesnt.
You could start by actually printing hit.collider.gameObject.name to see if it hits the wall or not.

Edit: I just saw you provide a 'playerMask' to your raycast. The raycast can only hit object in the provided layer. If your playerMask only contains the player, as the name suggests, then it wont hit anything other than the player. So it either hits nothing or your player.

Just to make this clear. Everything other than origin and direction is optional. You do not have to provide these parameters:
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

1 Like

Yeah, that was the problem!
OK, my initial thought was that the Raycast only returns true if the ray hits the PlayerMask, otherwise false (hence my true/false assigns at first). By just giving the Mask the floorLayer too, it now works fine.

Unless you specifically want to exclude some layers from the raycast, which generally speaking does not often make sense for a line of sight check, you can just not assign any layer mask to the raycast.
It will then check the default layers, which is basically everything.

1 Like