Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question Weird behaviors with transform.LookRotation when looking at position+Vector3

Discussion in 'Scripting' started by DONKEY40, May 26, 2024.

  1. DONKEY40

    DONKEY40

    Joined:
    Aug 18, 2022
    Posts:
    4
    Hello! I'm working on a character controller for an isometric retro shooter. However, when making the character rotate towards where they are moving, I encountered some issues.
    • The character doesn't fully rotate, instead of 90 degrees it's about 85.
    • The character's rotates sometimes lags and glitches when changing directions.
    Here is my code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerMove : MonoBehaviour
    6. {
    7.     public float MoveSpeed;
    8.     private CharacterController controller;
    9.     public Quaternion lookTo;
    10.  
    11.     private Vector3 move;
    12.     public Vector3 velocity; //For Debugging
    13.    
    14.     // Start is called before the first frame update
    15.     void Start()
    16.     {
    17.         controller = GetComponent<CharacterController>();
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.         float moveX = Input.GetAxis("Vertical")*MoveSpeed*-1f;
    24.         float moveY = Input.GetAxis("Horizontal")*MoveSpeed;
    25.         move = new Vector3(moveX, 0f, moveY);
    26.         velocity = controller.velocity;
    27.         lookTo = Quaternion.LookRotation(transform.position+controller.velocity);
    28.         lookTo.z = 0f;
    29.         lookTo.x = 0f;
    30.         transform.rotation = lookTo;
    31.      
    32.         controller.Move(move);
    33.     }
    34. }
    35.  
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,369
    As long as
    lookTo
    is a Quaternion, the above vlues values are NOT Euler angles. They're NOT for you to manipulate. They won't do what you think.

    Just move your player, then use LookAt() and make your player face the point you want.

    Here's more on why those fields are not what you think they are:

    All about Euler angles and rotations, by StarManta:

    https://starmanta.gitbooks.io/unitytipsredux/content/second-question.html

    Quaternion dumper if you insist on peeking inside the ugly parts:

    https://forum.unity.com/threads/making-a-random-item-hover.1450048/#post-9088465
     
    Bunny83 likes this.
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,194
    In addition to what Kurt said, you also seem to mix up even more suff here. First of all there's no "transform.LookRotation", there's a transform.LookAt method. This method actually takes a position in worldspace where the transform should look at, as well as a reference up vector to control the rotation around the look axis.

    Quaternion.LookRotation on the other hand is a static method that takes a direction vector in world space as well as a reference up vector like the LookAt method of the transform component.

    The LookAt method essentially just does this internally
    Code (CSharp):
    1. void LookAt(Vector3 aTarget, Vector3 up)
    2. {
    3.     Vector3 dir = aTarget - transform.position;
    4.     transform.rotation = Quaternion.LookRotation(dir, up);
    5. }
    However as Kurt said, you should not mess with the 4 values of a Quaternion. They are not euler angles. Rotations are represented by unit quaternions. Quaternions are a 4 dimensional number system. A unit quaternion means it always has a length of exactly 1.0. So it's essentially a point on a 4d hypersphere. When you mess with individual components, you would denormalize it. Unity often times does normalize the quaternion (for example when assinging it to transform.rotation), however the rotation would no longer be the same.

    If you want to cancel any up-down-rotation, you should zero out the y component of your direction vector. Since you don't explicitly pass an up vector, you implicitly pass Vector3.up anyways. So the roll would be 0 as well.

    Code (CSharp):
    1.         Vector3 dir = controller.velocity;
    2.         dir.y = 0f;
    3.         transform.rotation = Quaternion.LookRotation(dir);
    Keep in mind that passing an invalid direction ( that has all zero values ) usually cause issues or errors. So be careful when doing things like that with dynamic values.
     
  4. DONKEY40

    DONKEY40

    Joined:
    Aug 18, 2022
    Posts:
    4