Difference between CastCollider and CalculateDistance with ColliderDistanceInput?

Hi all,

I’m working on a basic DOTS character controller (send help!) so I can move on to some more fun parts of my project. If a certain DOTS character controller is released soon, I’ll definitely consider that. But I also want to understand more of how things work. I have a lot of things working pretty well, and the performance compared to the non DOTS approach is amazing, but I’m a little confused about the tools I have to use. Specifically CollisionWord’s CastCollider vs CalculateDistance.

In practice, I use CastCollider(ColliderCastInput, ref NativeList) to see if any obstacles are detected following the intended velocity. If something his hit, I then use CalculateDistance(ColliderDistanceInput, ref NativeList) at the intended position to pick up any obstacles and use the DistanceHit.Distance and DistanceHit.SurfaceNormal to push back out of any intersecting surfaces. This works, but I don’t understand the distinction between CastCollider and CalculateDistance here.

The hits returned both provide Fraction, RigidBodyIndex, ColliderKey, Material, Entity, Position, and SurfaceNormal. For DistanceHit, I believe Distance just returns Fraction. What is the distinction between the data stored in the hit structs?
EDIT: I think for ColliderHit, Fraction is the distance along the collider cast path where a hit occurred (0 to positive infinity), while for Distance Hit, Fraction/Distance is the distance from the collider surface where a hit was detected (negative infinity to positive infinity).

I also don’t understand the ColliderDistanceInput. A Collider is required, why is a RigidTransform also needed? What does MaxDistance do? I can’t tell if it increases the range of the query by real world units, or scale, or what. I think at 0 the query is just detecting things from the center to the surface of the collider.

CastCollider sweeps your collider in the specified direction. It gets a collider but also a transform of the collider (in case you want to transform it before the sweep, otherwise leave at identity). MaxDistance gives you how long a sweep you want to do, while Fraction gives you a percentage of the MaxDistance where hit was detected. Frac tion of 0 means you have an initial overlap.

CalculateDistance sweeps in all directions, not just one. Fraction is the absolute distance. The reason you need both is exactly as you described, to handle penetrations. Also distance query gives you penetration depth (say -0.1f) while cast will give you 0 in this case.

You might want to look at https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/UnityPhysicsSamples/Assets/Demos/6.%20Use%20Cases/CharacterController, it is using a lot of the logic you described, and may help you understand things a bit better.

3 Likes

Sorry, lost track of this for a bit. Your response was indeed helpful. I’ve been looking into the CharacterController demo and some other sources, but I think I just needed to hear some things stated another way. Also drawing lots of debug lines helps.

1 Like

Debug draw is the most useful tool when working with physics.