Recreatable incorrect raycast miss on capsule collider

I have found that some raycasts do not hit capsule colliders when they clearly should. I am not inexperienced with Unity’s physics and believe this is a serious bug and so I have found a setup that recreates the problem in hopes someone can find the problem.

Tests were run on Windows with a fresh Unity 2022.3.52f1 project in editor and build, using mono and IL2CPP.

The problem happens with many more rays but recorded 6 to demonstrate. All of these rays will result in a raycast miss on a default capsule gameobject with position (0,0,0), rotation (0,0,0), scale (1,1,1).

And after move the capsule along Y -0.001 they all hit.

If you wish to test this I have uploaded a scene and helper script to demonstrate
BrokenRaycast.zip (4.5 KB)
[Edit] Pastebin script if you prefer, just add the component to an empty gameobject: using System;using System.Collections;using System.Collections.Generic;usi - Pastebin.com

Or test yourself with this ray

  • origin (-0.4902608, 1.836351, 0.4888007),
  • direction (0.3221217, -0.8907961, -0.3204995)
  • length 2

Some interesting tests:

  • Rotating the capsule 180 degrees on X or Z, all raycasts become hits. This problem only occurs on the top of the capsule.
  • Rotating the capsule around Y any amount does not change the result
  • The ray origin/direction can be adjusted by a small amount and they will still be a miss. So the ‘hole’ has some width.
  • This was happening to me in an enviroment with many capsules of different radius and length across many positions, it is not related to the positioning or size of the capsule collider.
  • Extending the length of the raycast to reach the backface of the capsule will result in a hit

[Edit] When extending the length of these rays that miss, they all intersect the edge between the cylinder and bottom hemisphere (and create a backface hit).

8 Likes

This is an interesting problem, I shall look into this myself. However the trick to remember with raycasts is there are many values if we look at Point of Origin for example (center of the screen) and trace that 200f, it isnt actually calculating everything on its path, its calculating something at the 200f point, it is possible to pass through objects with a ray, or in some cases not pass through objects.

In any coding language, there has been a level of accuracy posed, hence Char, int, int64, float, long, uLong etc. float is not the most accurate and that 0.001 maybe a large difference.

I will however as I said test this as it seems fun to see why it is not working

1 Like

Thanks, I was hoping since this is a primitive collider type it would be more robust to accuracy. I do not feel this is the problem in this case due to the angle and location of the hole being repeated on capsules with many different transforms and sizes.

An additional point of interest I just found, all these raycasts hit the edge of the bottom hemisphere.

2 Likes

possibly a math inaccuracy related to pi/spheres
effectively resulting in a seam where the physics can pass through due to rounding error perhaps?

2 Likes

Is the 4888007 part a typo? Because that’s a huge enough number to cause significant floating point error… when cast those rays might not be anywhere near the collider…

Floating (float) point imprecision:

Never test floating point (float) quantities for equality / inequality. Here’s why:

https://starmanta.gitbooks.io/unitytipsredux/content/floating-point.html

“Think of [floating point] as JPEG of numbers.” - orionsyndrome on the Unity3D Forums

Scientific notation (numbers that look like 1.2345e-07 for instance):

1 Like

Sorry yes that is a typo I have now amended. Your answer is very good if that was the case thank you, but I think it is something else.

1 Like

I don’t mean it can’t be a floating point issue, just that I don’t think its due to the ray or capsule being gigantic or far from the origin.

1 Like

I think you’re right! That’s wild… I confirmed it easily even back in ancient Unity3D 5.6.6f2 with my own setup and your numerals. WOW… it totally misses until you wiggle something a bit.

I am now going to go into pure 100% random wild guess to explain this bug: It is some weird interaction between the two spheres at each end and the cylinder check… like it is determined to hit one from the inside and then the other isn’t checked. That’s my SWAG.

I’d love it if someone from Unity can offer insight here…

My code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RayToCapsule : MonoBehaviour
{
	[Header( "You can drag these in and modify them in editor,")]
	[Header( "... or see what they are initted to in Start();")]
	public Transform From;
	public Transform To;

	void Start()
	{
		// numbers from original post:
		//
		// https://discussions.unity.com/t/recreatable-incorrect-raycast-miss-on-capsule-collider/1556381
		//
		// Verified that this From / To combination does NOT hit the capsule in Unity5!!

		From.position = new Vector3(-0.4902608f, 1.836351f, 0.4888007f);
		Vector3 direction = new Vector3(0.3221217f, -0.8907961f, -0.3204995f);
		float length = 2.0f;
		To.position = From.position + direction.normalized * length;
	}

	void Update ()
	{
		Ray ray = new Ray(origin: From.position, direction: To.position - From.position);

		RaycastHit rch;

		bool hit = false;

		if (Physics.Raycast( ray, out rch, maxDistance: 2))
		{
			hit = true;
		}

		Color color = hit ? Color.green : Color.white;

		Debug.DrawLine(From.position, To.position, color);
	}
}

Enclosed is the package with micro-scene setup.

RayToCapsule.unitypackage (3.9 KB)

1 Like

Thanks for checking, I was starting to feel like I was just going mad. I’m thinking similar. It happens only to the top of the capsule as if the bottom is checked first. Hope someone at Unity could give answers.

I have a few more example rays if needed

position: {x: -0.4902608, y: 1.8363508, z: 0.4888007}
direction: {x: 0.3221217, y: -0.8907961, z: -0.3204995}
length: 2

position: {x: -0.7098993, y: 1.824118, z: 0.09058686}
direction: {x: 0.4597884, y: -0.886148, z: -0.05776308}
length: 2

position: {x: -0.13400137, y: 1.8419594, z: -0.6680061}
direction: {x: 0.08928909, y: -0.892894, z: 0.4413251}
length: 2

position: {x: 0.4052222, y: 1.8211911, z: 0.5965029}
direction: {x: -0.2632183, y: -0.885008, z: -0.3840276}
length: 2

position: {x: 0.6856232, y: 1.822818, z: -0.21349709}
direction: {x: -0.4426994, y: -0.8856416, z: 0.1402011}
length: 2

position: {x: 0.5561909, y: 1.8168975, z: -0.4713927}
direction: {x: -0.3555751, y: -0.8834435, z: 0.3051132}
length: 2

2 Likes

When I am home I shall happily check all these theories, in general though do remember: Simple collider - means less calculations at run time, they are not specifically designed to be used for complex procedures (Raycasting) being one. The more complex the collider, the more accurate your results, but the slower the calculations. It may well be a combination of all the theories posted here. Floating point imprecision, gaps in colliders etc.

The positive take-away from this is it has brought people together to identify an issue and potentially create fixes for it, I can ask Unity what they think on the subject, but I doubt there is too much they can do for a simple collider like the capsule. It is there mainly for greyboxing after all

1 Like

Thanks, I would like to get some higher up eyes on this and get an answer.

1 Like

Contacted them, I will report back if I get a response, it may take a day or two though. Will be interesting to see their opinion on this. Its not breaking anything but it could be a challenge for people to try and fix, which gives you chance to learn how to make a collider :wink:

Very interesting.

i am commenting to keep the engagement high so it gets noticed by unity folks. :smiley:

also are you checking on update or fixed update?

Blockquote
also are you checking on update or fixed update?

Tested both, both still miss.

Strange! Just for fun, have you tried different Physics.Raycast(...) overloads? I remember filing a bug report years ago, where certain overloads including the layerMask argument failed or passed differently compared to others

Nice one mate.

Are rays has the same crossing Point? Is it a upper sphere center?

I tested the Pastebin script on Unity 6000.0.23f1 (Windows 10) and reproduced the problem.
Additionally, I ran a million tests with the following random angle ray and observed 67 failures. This is clearly an unusual number, and I became convinced that it is a bug.

int errorCount = 0;
Random.InitState(1234);
for (int i = 0; i < 1000000; ++i)
{
    var rayDir = Quaternion.Euler(Random.Range(0f, 360f), Random.Range(0f, 360f), Random.Range(0f, 360f)) * Vector3.right;
    var rayOrigin = -2f * rayDir + new Vector3(0f, 0.5f, 0f);

    if (!Physics.Raycast(rayOrigin, rayDir, rayLength))
        ++errorCount;
}
if (errorCount > 0)
    Debug.Log($"error! {errorCount}");

I quickly reviewed PhysX’s ray vs. capsule intersection algorithm, which is a general method that divides the capsule into a cylindrical side and two hemispheres, solving a quadratic equation for each.
Such algorithms can potentially encounter precision issues in the following cases:

  • The ray or capsule is (relatively/absolutely) extremely (large/small).
  • The capsule’s length is very short (but still larger than the algorithm’s threshold).
  • The capsule’s orientation and the ray’s direction are nearly parallel.

However, none of these conditions apply to this case, so I believe it is not a precision error issue.

If you have not yet submitted a bug report, please do so.

Only one way that happens: file a bug.

Because a forum post is not a bug report, NO ACTION will be taken on this post, no matter how long the thread gets.

If you have a bug (and I confirm you have a bug above, with a SUPER tiny micro project reproduction scenario… perfect for filing!), there is only one way to report it.

Help → Report A Bug.

Make a blank project, type in your numbers, report it.

Report one bug at a time with all the expected supporting information attached.

Any other way is NOT a bug report and is NOT going to change anything.

Saw this on reddit, but glad you posted it here too.

Figured there had to be a bug in your code, perhaps moving the collider and forgetting that Unity no longer automatically syncs the Physics, but nope, once I got on my PC and grabbed the pastebin code it is as simple as it can be!

I wonder if this potential failure case can also apply to other type of collisions, such as overlaps or primitive casts? I’d like to think not as they would be using different algorithms/equations, but as its unclear as to why exactly the capsule test is failing I don’t know if we can be sure.

I’m sure others have tried this, but adding a sphere at the exact same location as the top sphere of the capsule does correctly trigger hits. Not exactly 100% fool-proof as floating point issues could be changing the position/alignment vs the capsule top sphere, but its another useful point of data.

More so if anyone is really concerned about this bug, it should mean you could augment the capsule with additional 2 spheres.

Anyway just wanted to add a post to thank you for posting this and logging a bug report. Please keep this thread updated with any results and don’t let Unity fob you off. While it is likely tricky due to probably being an issue with PhysX, this really needs to be addressed one way or another.