Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Help Wanted Quarternion.LookRotation is only rotating my game object on one axis, why is this?

Discussion in 'Scripting' started by KingpinKeys, Sep 23, 2020.

  1. KingpinKeys

    KingpinKeys

    Joined:
    Mar 5, 2019
    Posts:
    9
    I am using Quaternion.LookRotation to change the rotation of a gameobject to a new rotation determined by a ray trace. Here is the script:

    Code (CSharp):
    1.  using UnityEngine;
    2. public class Example : MonoBehaviour
    3. {
    4.  
    5. public float speed = 0.5f;
    6. private Vector3 targetPos;
    7. private Vector3 startPos;
    8. private Vector3 mousePos;
    9.  
    10.  
    11. public void Start()
    12. {
    13.      startPos = transform.position;
    14. }
    15. public void Update()
    16. {
    17.  
    18.          mousePos = Input.mousePosition;
    19.          Ray mouseCast = Camera.main.ScreenPointToRay(mousePos);
    20.          Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
    21.          RaycastHit hit;
    22.          float rayLength;
    23.          if (Physics.Raycast(mouseCast, out hit, 9999))
    24.          {
    25.              Debug.DrawLine(mousePos, targetPos, Color.blue);
    26.              targetPos = new Vector3(hit.point.x, 0f, hit.point.z);
    27.  
    28.  
    29.              if (Vector3.Distance(targetPos, transform.position) >= 0.5f)
    30.              {
    31.  
    32.              Quaternion rot = Quaternion.LookRotation(targetPos);
    33.              transform.rotation = Quaternion.Slerp(transform.rotation, rot, speed * Time.deltaTime);
    34.  
    35.              Debug.Log(targetPos);
    36.          }
    37.      }
    38.  
    39. }
    40. }
    I'm currently getting this result in my scene:


    This is the desired result however I want the X axis to also change. For example when I use something simple like transform.LookAt(targetPos) I get the desired result however I can't do this function overtime like I can with RotateTowards. This is the result I get using LookAt instead of RotateTowards:

    The latter method is what I ideally want to achieve however I don't want the rotation to happen in just one frame I want the turret to slowly pan over to the new rotation just like the first method. How can I pull both these methods together to fit my needs?
     
  2. LilFire

    LilFire

    Joined:
    Jul 11, 2017
    Posts:
    62
    LookRotation is used to create a rotation with 2 vectors (forward and upward). In your case, the default upward is Vector3.up
     
  3. KingpinKeys

    KingpinKeys

    Joined:
    Mar 5, 2019
    Posts:
    9
    What value should I plug in instead of the default Vector3.up in order to have the object rotate on both axis?
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,006
    It IS looking in multiple axes, but the data you're sending it is on a flat plane.

    Unlike transform.LookAt, Quaternion.LookRotation has NO idea of the object it will be applied to. That means it doesn't know where it's looking from. So instead of feeding it a position, as you're doing, what you actually need to do is feed it a direction vector. You can get a direction vector by subtracting two positions.

    These two pieces of code will produce identical results:
    Code (csharp):
    1. transform.LookAt(point);
    2.  
    3. transform.rotation = Quaternion.LookRotation(point - transform.position);
     
    PraetorBlue likes this.
  5. KingpinKeys

    KingpinKeys

    Joined:
    Mar 5, 2019
    Posts:
    9
    Thank you for the solution it worked perfectly, so is the reason why it works with LookAt because of the Vector3 WorldUp parameter so it can actually find the ray trace hit position? Again thank you for the quick reply :)
     
  6. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,006
    The reason it works with LookAt is because LookAt knows where your object is.

    Try this. Currently, your turret's base is at (0,0,0) and your actual turret is above that. Try moving your turret, say, to the left. Now aim at a point in between the old spot and the new spot. With transform.LookAt, it'll look right at the point you're aiming at. With Quaternion.LookRotation [without subtracting transform.position], it'll be looking in the wrong direction entirely. No matter where your turret's position is, Quaternion.LookRotation will always point as if the turret is looking from (0,0,0) because it's treating a position as a direction vector. That's why you need to subtract the turret's position when using LookRotation.
     
    PraetorBlue likes this.
unityunity