Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Explanation Of Vector3.Cross With Quaternion.LookRotation

Discussion in 'Scripting' started by MackerelShark, Jun 25, 2022.

  1. MackerelShark

    MackerelShark

    Joined:
    Feb 10, 2022
    Posts:
    2
    Cross-posted from Unity Questions, since I've gotten no replies there.

    Hoping someone can explain the math behind this:

    I am working on a survival game and needed to rotate walking animals to match the slope of the terrain under them without affecting the direction they were pointing. IE, they needed to rotate in the local Y axis, without affecting their local X and Z axes.

    After a lot of searching and trouble I came across this code:

    Code (CSharp):
    1.          
    2. RaycastHit hit;          
    3.          if(Physics.SphereCast(transform.position, 0.5f, -(transform.up), out hit, yourDistenceToGroundYouWant, yourGroundLayers))
    4.          {
    5.           transform.rotation = Quaternion.LookRotation(Vector3.Cross(transform.right, hit2.normal)
    6.          }
    It's on this thread, for some context: https://answers.unity.com/questions...layer-to-match-terrain-slope.html#answer-form

    It was practically a 1 to 1 drop in to my own script, resulting in this:
    Code (CSharp):
    1. RaycastHit hit;          
    2. if (Physics.Raycast(transform.position, -Vector3.up, out hit))
    3. {
    4. transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(Vector3.Cross(transform.right, hit.normal)), .01f);
    5. }
    6.          
    7.  
    Now, no complaints from me and I'm really grateful to @Fanttum for the answer, but what is bothering me is that I don't know WHY this code does what it does. Quaternions are mystery oil to me; could someone spread some enlightenment here, so I'm not just another copy-paste-codemonkey in this regard?

    Thanks!

     
  2. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,596
    Code (CSharp):
    1. Vector3.Cross(transform.right, hit.normal)
    When you cross product two Vectors, you get a resulting Vector which is perpendicular to both of these. This results in either a Vector pointing in either the forward or backward direction in which we want our object to face. Which one depends on the order of the cross product, but in this case, it's the forward.

    Code (CSharp):
    1. Quaternion.LookRotation(vector)
    This just turns our resulting vector into a Quaternion. Since there's no second optional parameter, according to the documentation, it gives us a Quaternion rotation where our object is facing in the correct forward pose, with up, being up.
     
  3. MackerelShark

    MackerelShark

    Joined:
    Feb 10, 2022
    Posts:
    2
    So, if I understand this correctly:

    This code is using Vector3.Cross to compare the transform's current "rotation.x" and the normal's "rotation.y" and generate a new Vector3. IE, it effectively "levels" the transform around it's own "X" in reference to the ground's "UP" direction. As a result of comparing the two Vectors, it effectively reorients the animal's "UP" without affecting or referencing it's rotation around that same axis?
     
  4. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,596
    Calling them rotations is incorrect, as they're Vectors, which is a rotation with a distance, but in this case the distance does not matter.

    If you call
    transform.right
    , it will return a Vector pointing in the direction of the object's right. For example, if you called Transform.right on an object with no rotation, it would be (1, 0, 0), but if you called it and it was turned around, it would return (-1, 0, 0). A normal also returns a Vector, not a rotation value. A normal is the vector pointing directly away from the surface, usually (0, 1, 0) when from a flat ground.
     
    Bunny83 likes this.