Fixed distance from object surface normal

I’m trying to get an object to follow in front of a player that moves along a track. The player can travel along the ground, up inclines, and up walls. Now, I need this object in front to rotate with and hover above the track by about 2 units.

I have something like this:

obj.transform.position = obj.transform.position + (obj.transform.up * (hit.point.y * 2));

This works while on horizontal ground but when going up a ramp onto a wall, not so well. Obviously, I can’t just use my raycast hit.point.y (which is being cast down from the object’s bottom) if the object is rotating and traveling vertically up a wall.

Any ideas how to incorporate the surface normal and angle of the ground into this? Or some entirely different solution?


I am not quite sure how to work this into your existing math given what you’ve provided. However here is a solution that may help you. This is in C#.

Since you say you are casting a ray down to the surface below you, then you can use the normal of surface point you hit to rotate your object.

	RaycastHit ray;
	if (Physics.Raycast(transform.position,Vector3.down,out ray,5.0f)) {
		transform.rotation = Quaternion.LookRotation(ray.normal);

I actually have the rotation (smooth) figured out:

var targetRotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
camTarget.transform.rotation = Quaternion.Slerp(camTarget.transform.rotation, targetRotation, Time.deltaTime * 8);

I wasn’t really explaining my problem very well, so I’ll include some pictures. I want the object (the box) to always be 2 units away from the floor, no matter what angle the floor is at.

Ex #1: It’s sitting nicely above the ground at 2 units and 4 units in front of the player.
alt text

Ex #2: As it approaches the incline it’s rotating nicely based on the normal but is not 2 units away from the floor.
alt text

Ex #3: Now it’s beginning to intersect the wall because it’s 4 units away from the player and 2 units above the player.
alt text

There must be away to use hit.normal and hit.point in combination to have this object always 2 units away from the floor or wall; I’m just stumped as to how…

To always keep an object a set distance away from a surface (this works on curves etc too), you have to:

  1. Shoot a Physics.Raycast onto any surface so that Unity can give you the direction of which way the surface is facing aka the direction perpendicular to the surface (called the normal).

  2. Multiply the surface normal (RaycastHit.normal) with however far you want your object away from the surface.

  3. Add the multiplied surface normal to where the raycast ended up hitting (RaycastHit.point).

    float distanceAwayFromSurface = .5f;
    RaycastHit hit;

    if(Physics.Raycast(rayOrigin, rayDirection, out hit, rayDistance))
    transform.position = hit.point + hit.normal * distanceAwayFromSurface;