Align Transform to Normal

martymarty Posts: 112Member

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!

Answers

  • TwistedTwiglegTwistedTwigleg Posts: 842Admin

    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))
  • martymarty Posts: 112Member

    How about with a KinematicBody - would that change anything?

  • TwistedTwiglegTwistedTwigleg Posts: 842Admin

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

  • martymarty Posts: 112Member

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

    Any other ideas? Anyone?

  • TwistedTwiglegTwistedTwigleg Posts: 842Admin
    edited February 10

    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.

  • martymarty Posts: 112Member
    edited February 10

    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!

  • martymarty Posts: 112Member
    edited February 10

    Deleted

  • TwistedTwiglegTwistedTwigleg Posts: 842Admin
    Answer ✓

    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)

  • MagicLordMagicLord Posts: 578Unconfirmed
    edited February 10

    @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

  • martymarty Posts: 112Member

    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.

  • TwistedTwiglegTwistedTwigleg Posts: 842Admin

    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:

  • martymarty Posts: 112Member

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

Sign In or Register to comment.