How to get the forward direction of a normal?

I have a Bike that travels down a race track, the track is one long mesh. I have a rectangular object, let’s call him Ben, that sits under the bike that has the below script on him, the bike will eventually Lerp it’s Y rotation to Ben’s Y rotation.

Ben casts a red ray straight down, obtains the normal vector of the object below, and matches it’s rotation.
It’s working fine for the X and Z values, but not for Y, which is the one I need. Ben also casts a green ray sideways to detect the edge of the road.

How do I rotate Ben to have the same Y rotation as the normal directly below him?

Or rather, how do I make Ben face down the track? I want his Y rotation perfectly aligned with the white lines on the road as it passes over them.

    function Update ()
    {
        OrientThisToObjectBelow(transform.TransformDirection(-Vector3.up));
    }
    
    function OrientThisToObjectBelow (dir : Vector3)
    {
        if (Physics.Raycast (transform.position, dir, hit, 150, LayerMask))
        {
            Debug.DrawLine(transform.position, hit.point, Color.red);
            transform.up = hit.normal;
        }
    }

alt text

There’s various solutions to this kind of problem, depending on exactly the effect you want. Ultimately what you’re trying to do is take your biker, who has 1 rotation, and ‘constrain’ it, to obey some specific rules.

Unfortunately the first problem here is what direction is ‘along the track’. The normal to the track is the vector directly upwards from it, not along it. Perhaps the simplest way to do this (without using additional libraries and things) would be to add a set of invisible ‘way points’ to the track, each oriented so that its z axis (tranform.forwards) points along the track. Then as a first version you can simply find the closest way point and quite simply set the biker’s rotation to be the same as the way point’s rotation. If the biker is a rigid body you’ll want to use rigidbody.MoveRotation, otherwise just set the transform.rotation value directly.

Going on from that, once you have it working you’ll find the biker appears to move along fine, however when heading round curves he’ll suddenly ‘snap’ to the orientation of the next way point. To solve this you could slerp from the rotation of the previous way point to the rotation of the next way point as the biker approaches it. If you wanted to get really smooth you could even look into catmull rom interpolation, but I’d wait and see if you need it first!

You may find with more complex tracks the simple ‘what way point am I closest to’ isn’t the correct metric (for example, it might fail when going round a 180 degree bend). In this case, you’ll probably need to handle it either by numbering the way points, or setting them up as trigger zones that cover the road, so the biker always knows exactly which way point he is in.

If you need to get cleverer and start doing things like allowing the biker’s orientation to change slightly under physics or change due to leaning as he goes round corners, you’ll hit the scenario where you want to manipulate the rotation in more complex ways. Once you get there, look up Quaternion.FromToRotation and its uses, which gives you a rotation that when applied will make one vector point in the same direction as another

Hope that helps :slight_smile:

-Chris