There are several approaches to your problem.
1) Cast your ray inside the player
Raycast() will ignore a collider if the ray starts inside it. Lets say your player is a cube at position (0,0,0) with a scale of (1,1,1). A ray from (0,0,0) with direction (1,0,0), i.e., along the x-axis, will not hit the player. If you move the ray's starting position to (-2,0,0), the ray will hit the player.
This may get complicated if your player consists of several collider and you want to cast the ray into different directions. You could literally shoot yourself in the foot (with a ray starting in the head) :)
2) Use layers
You can assign game objects to different layers. Then you can specify a layer mask and tell Raycast() the layers you want to hit.
A step-by-step tutorial to create and assign layers can be found in the manual. If you followed the steps and set layer #8 as your player layer, the following code will ignore all objects in the player layer.
// Bit shift the index of the layer (8) to get a bit mask
int layerMask = 1 << 8;
// This would cast rays only against colliders in layer 8, so we just inverse the mask.
layerMask = ~layerMask;
if (Physics.Raycast(transform.position, fwd, 10, layerMask)) {
// hit something not in the player layer
}
3) Get all colliders that intersect the ray
By using RaycastAll() you get an array of all colliders that intersect with the ray. Then you can sort out the ones you don't want.
RaycastHit[] allHits;
allHits = Physics.RaycastAll(transform.position, fwd, 10);
foreach (var hit in allHits)
{
// now filter by tag or name
if (!hit.transform.tag.equals("Player")) {
// yeah, we didn't hit something tagged as "Player"
}
}
Answer from Stefan Hoffmann on Stack OverflowWhy can't I use a raycast while standing inside a collider?
c# - Raycast but ignore the collider of the gameobject it's being called from - Stack Overflow
Raycast from inside a collider
Is there any way to get the collider of a raycast? - Unity Engine - Unity Discussions
Videos
There are several approaches to your problem.
1) Cast your ray inside the player
Raycast() will ignore a collider if the ray starts inside it. Lets say your player is a cube at position (0,0,0) with a scale of (1,1,1). A ray from (0,0,0) with direction (1,0,0), i.e., along the x-axis, will not hit the player. If you move the ray's starting position to (-2,0,0), the ray will hit the player.
This may get complicated if your player consists of several collider and you want to cast the ray into different directions. You could literally shoot yourself in the foot (with a ray starting in the head) :)
2) Use layers
You can assign game objects to different layers. Then you can specify a layer mask and tell Raycast() the layers you want to hit.
A step-by-step tutorial to create and assign layers can be found in the manual. If you followed the steps and set layer #8 as your player layer, the following code will ignore all objects in the player layer.
// Bit shift the index of the layer (8) to get a bit mask
int layerMask = 1 << 8;
// This would cast rays only against colliders in layer 8, so we just inverse the mask.
layerMask = ~layerMask;
if (Physics.Raycast(transform.position, fwd, 10, layerMask)) {
// hit something not in the player layer
}
3) Get all colliders that intersect the ray
By using RaycastAll() you get an array of all colliders that intersect with the ray. Then you can sort out the ones you don't want.
RaycastHit[] allHits;
allHits = Physics.RaycastAll(transform.position, fwd, 10);
foreach (var hit in allHits)
{
// now filter by tag or name
if (!hit.transform.tag.equals("Player")) {
// yeah, we didn't hit something tagged as "Player"
}
}
I recently had this problem. It was a pain to figure out, yet it is a simple fix.
I found that if you go to Edit -> Project Settings -> Physics2d and Uncheck the box that says "Raycasts Start In Colliders" it solves this issue.
This makes it so that you do not have to deal with layers (I find layers to be a very impractical way of selectively raycasting). It just ignores the collider on the gameobject casting the ray, so you can have multiple prefabs of players/enemies casting rays and hitting each other, but not themselves.
Hello!
I am looking for ways to raycast from the inside of a collider or trigger.
As the documentation says, rays starting inside a collider will not detect said collider - but I require some method to do it, so as to keep the code clean, robust and reliable.
I know there's the `Physics.queriesHitBackfaces` option, but that doesn't work for non-mesh colliders.
I know it's possible to trace the ray backwards (from the target position towards the player), but that doesn't account for larger colliders and can lead to hitting a different collider altogether.
How else can I detect the ray already begins within the collider it can hit?
I mainly require this to improve the gameplay experience, for instance:
- Player interacts with a ladder; By pressing E on it, they get attached, and by pressing E again they detach. During the attachment process, the player is moved slowly into the ladder's trigger, so pressing E while looking anywhere should detach the player (I don't want them to pixelhunt for the ladder entity again). This can be accomplished by caching the ladder entity when it is hit and if player presses E while in an 'attached' state they get detached, but again you can see that this is not robust nor stateless at all, compared to using the same system for attachment/detachment.
- Player is inside 'water' trigger; firing their gun from the inside of the water has a different effect on the bullet than firing it from outside towards it - perhaps the player can't fire while inside, making the check trivial (if (hit_distance < threshold) return; ) compared to having a boolean flag for 'isUnderwater' and then somehow estimating if the portion of the collider is below its surface, when a simple raycast could do just fine.
Thank you for any suggestions. This really feels like a major oversight, if there's no reliable way.
I haven't worked with Unity meshes for a while but maybe add the sharedMesh of your MeshCollider after you added the verticies and triangles to your Mesh. Maybe the MeshCollider uses the verticies and triangles of the Mesh at the time of assignment and not the updated values if it changes overtime.
As far as I am aware in order for the raycast to catch the mesh collider it needs to be marked as "Convex" in the inspector.
Otherwise you could enable the convex configuration in runtime through a script however the inspector option is always a bit better because you can then see if the collider matches your shape!
This could be another reason why your raycast cannot catch it! your collider needs to match the shape of your object! This explains why you can catch sphere and box colliders but not mesh colliders (assuming that they are marked as convex to begin with) since the sphere and box have specific shapes that the raycast collides and triggers. Of course make sure that the layers and tags are appropriate as well!