Raycast Ignores Objects

Hello everyone, I making top-down space shooter game.
I use raycast to see if the enemy is aiming directly at the player, in which case he fires of the primary weapons (blasters, lasers, plasma).

        RaycastHit[] hits;
        ray = new Ray (transform.position, transform.TransformDirection (Vector3.down * range));
        hits = Physics.RaycastAll (ray, range);
        for (int l = 0; l < hits.Length; l++) {
            if (shoot <= Time.time && hits[l].transform.tag == "PlayerShip") {
                              //Shooting code
                }
                shoot = Time.time + fireRate;
            }
        }

for some reason raycast often ignores player’s space ship object.
I do not see any sense, I did not write anything like RandomIgnorePlayer.cs.
The player has a mesh collider and rigidbody. It is tagged as “PlayerShip” and has a layer named “PlayerShip” (currently unused, may be useful later).
According to me it looks as if raycast responded only to the origin of the object (due to inaccuracies in the float misses), in which case there must be a way to respond to the collider and not at the origin.

Note: All my models are made in a Blender, Vector3.down actually aim forward.
ps. sorry for bad English, I am Czech, English I can not very well.

Have you made sure that the physics settings are correct? (That is Edit/Project Settings/Physics).

Have you tried to set the fireRate to zero or similar to get it to shoot all the time, that should make it easier to see if it actually misses?

Have you tried using Debug.DrawRay to draw the ray, so that you can see if it is correct?

You can probably replace “transform.TransformDirection(Vector3.down* range)” with "transform.down, but that shouldn’t change the results.

Thank you for trying to help me.
Setting physics: It is wrong when it looks like this (see. Figure)?
2903514--213798--Settings.png
Yes, Debug.drawRay () I tried, as you can see ray goes straight through the player’s spaceship (fireRate is set to 0).
2903514--213802--Game-ray.png
it looks like it really is some inaccuracy float, under certain angles and at close distance, enemy fire.
2903514--213803--Game-close.png
I use this code to turn the enemy towards the player … maybe there is an mistake :

        Quaternion dir = Quaternion.LookRotation (player.transform.position - transform.position);
        dir = Quaternion.Euler (dir.eulerAngles.x - 90, dir.eulerAngles.y, dir.eulerAngles.z);
        rb.MoveRotation (Quaternion.Slerp (transform.rotation, dir, rotateSpeed * Time.deltaTime));

Figure 1) The Physics Settings look right, providing that the layers are correctly assigned.

Figure 2) I agree that the debug.draw looks dead on. However, have you paused and looked at it from different angles? Perhaps it is a bit off in one of the angles? Is the ray as long as “distance”? So, you are sure that it actually is within distance.

Figure 3) When you are really close, there is a chance that the raycast will start within a collider and rays will not intersect with colliders which have the origin of the ray inside of them.

Everything looks just right and it certainly is a bit of a mystery as to why it doesn’t work.

But, I’ll give you a bit of code review, which shouldn’t affect anything :slight_smile:

        // You will want to preallocate these and use Physics.RaycastNonAlloc to get better performance
        RaycastHit[] hits;
        // Skip the range-part, this is supposed to be a normalized direction
        // Also, you could probably use something like transform.down instead of doing a TransformDirection
        ray = new Ray (transform.position, transform.TransformDirection (Vector3.down));
        // You will want to use Physics.RaycastNonAlloc to get better performance
        hits = Physics.RaycastAll (ray, range);
        for (int l = 0; l < hits.Length; l++) {
            // Using .tag == allocates memory, causing garbage collection in the end
            // CompateTag is better
            if (shoot <= Time.time && hits[l].transform.CompateTag("PlayerShip")) {
                              //Shooting code
                } // is this just something that didn't get deleted from the shooting code? In that case disregard the following comment
             // Shouldn't this be in the if? Else you might skip shots?
             shoot = Time.time + fireRate;
            }
        }

As for part two of the code, just a nitpick

Quaternion dir = Quaternion.LookRotation (player.transform.position - transform.position);
        dir = Quaternion.Euler (dir.eulerAngles.x - 90, dir.eulerAngles.y, dir.eulerAngles.z);
        // Am I the only one who doesn't like this usage of lerps?
        rb.MoveRotation (Quaternion.Slerp (transform.rotation, dir, rotateSpeed * Time.deltaTime));
1 Like

You’re a genius. I never thought of looking at the scene from the side … it seems that the ray just slashed the bottom of spaceships …
2903885--213847--StupidMistake.png
I’ll have to adjust the origin of my models.
Thank you for your help :slight_smile:

1 Like