Proper way to deal with float precision?

Hi everyone,
I’m fairly new to Unreal, still trying to find my way around it all. I ran into this issue while writing my own character movement component: The character can get ever so slighly stuck inside some blocking geometry, with the penetration depth being something like 0.000015cm. Oh well, I’ll just move the character out of the penetration. Problem is, since the penetration depth is so small, it’s only ever going to work if I’m near the world origin, otherwise adding a vector of that length to the character’s position does absolutely nothing because there’s not enough precision. It doesn’t help that Unreal insists on using centimeters as the unit, and there seems to be no way to change that.

What’s the proper way to deal with a situation like this? I read somewhere that you should just move the world origin instead to keep the numbers smaller, I tried it and determined that I’d need to move it every 2 meters or so for it to work and I refuse to believe this is the correct solution. Is there a way to tell the collision detection to ignore offsets of this scale?

Thanks in advance!

How about you move it 0.1 cm? The player won’t notice (unless your game is about tiny insects or something.)

One of the problems is that the physics engine typically transforms one object into the others’ local space, and does resolution, rather than keep both in world space, but when you move an object, you can only use world space coordinates, so you end up with these “narrow” cases. This is because floating point values are, essentially, a hack (a userful hack!) and working around this hack with local coordinate transforms put two hacks on top of each other, so to compensate for that, you need to add a third hack: use a separating distance that’s large enough for the extent of world you want to use.

Yeah the solution is to just move it further. Changing units wouldn’t really matter, you’d just be dealing with even smaller numbers. Look at UMovementComponent::ResolvePenetration() and UMovementComponent::GetPenetrationAdjustment(), which do something like this, using global epsilon values.

Moving world origin is an expensive operation, especially once the number of actors in the level starts increasing.

Yep, increasing the minimum depenetration distance did the trick, thanks!