- Home /
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?
Thanks!
Answer by Atrius · Apr 14, 2012 at 02:11 AM
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);
}
Pretty good solution, given the complexity of other fixes that come to $$anonymous$$d. $$anonymous$$ight be useful to quickly rotate, rather than snapping (can cause some nasty effects, especially if we're snapping a character with an attached camera). Various lerp functions could allow direct control of that, or there's always `Quaternion.RotateTowards()`.
Answer by oneslyfox · Apr 14, 2012 at 06:25 PM
I actually have the rotation (smooth) figured out:
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][1] 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][2] 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][3] 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... [1]: http://s17.postimage.org/8g3o7lwxb/ex1.jpg [2]: http://s15.postimage.org/rirovozh7/ex2.jpg [3]: http://s13.postimage.org/441adde47/ex3.jpgvar targetRotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
Answer by schkorpio · Apr 21, 2017 at 09:31 AM
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;
}
Your answer
Follow this Question
Related Questions
How do I obtain the surface normal for a point on a collider (can't use RaycastHit.normal)? 3 Answers
Hovering smoothly at one height 1 Answer
Mesh triagnles/surface with normals 1 Answer
Assigning vertex normal in Surface program to o.Normal brakes lighting? 0 Answers
Too many texture interpolators would be used for ForwardBase pass (again) 1 Answer