• 3D
  • Align Transform to Normal

Hey, all!

If I have a normal (from a RayCast) in a Vector3, how can I set a RigidBody's rotational transform to align with that normal?

TIA!

If you are wanting to use the normal vector as a rotational vector, then you could do this: (untested)

"rigid = your RigidBody, n_vec = the normal vector" rigid.global_transform.basis = Basis(n_vec) That should make it point in the same direction as the normal. To make it face the normal, you have to invert the normal: (untested)

var inverse_n_vec = n_vect.inverse() rigid.global_transform.basis = Basis(inverse_n_vec)


Those may not work though but this should work, or at least has a higher chance of working: (untested)

"rigid = your RigidBody" "n_vec = the normal from the raycast" "n_pos = the hit position from the raycast" var hit_pos = n_pos + n_vec # may need to subtract n_vec, I'm not sure rigid.global_transform = rigid.global_transform.looking_at(hit_pos, Vector3(0, 1, 0))

How about with a KinematicBody - would that change anything?

It should work with any of the spatial based nodes :smile:

I really, really appreciate your examples, but they just don't seem to work. Even after massive noob tweaking. ;-)

Any other ideas? Anyone?

Well, I tried changing basis using the normal and yeah, it doesn't work... :sweat_smile:

I made a project using look_at and it follows the normal. I've attached the test project I used. Hopefully it will help. It follows the collision point as opposed to the ray normal. I'm not sure if it will help, since (technically) it's not what you asked for, but it may help as it shows how to make an object rotate to follow a ray's collision.

Thanks for the demo, but it doesn't really help.

Your demo is an awesome example of how to place an object at a ray collision point. But I already know how to do that. What I don't know is how to then have that object then align itself to the normal at the collision point. In your demo, the object that you named RayPoint is simply placed on the face of the target sphere using RayCast but not oriented in any way.

Thanks again for you help!

Done!

I think I've managed to make an example that does what you want: RayPoint now faces the raycast normal. There is probably a better way to do it, but I just implemented the first way that came to mind. (Had to delete the old project to send the new one)

@marty said: Hey, all!

If I have a normal (from a RayCast) in a Vector3, how can I set a RigidBody's rotational transform to align with that normal?

TIA!

Some pseudo code

var directionInverse = Vec3(-normal.x , normal.y, -normal.z) NodeObject.global_transform.basis.z = directionInverse

or try NodeObject.transform.basis.z = directionInverse

There is many ways, and i'm confused about transform and global_transform :D

Your example works great, TT!

I've used LookAt for this kind of thing in Unity and SW3D, I was just hoping that was a more direct way to copy a set of quaternions, seems like that might be more performant. Guess not though. ;-)

Thanks for your suggestion too, ML.

They may be a direct way using quaternions, but I'm not sure what it would be. I just default to using LookAt because it's easier and since it's using C++ and not GDScript, it should be fairly decent for performance (since C++ faster than GDScript for most things).

Glad it works :smile:

I agree. I worked out a solution with GDScript Quat.slerp-ing but it's both slower and less reliable.