After rotation, object moves forward in old (mouse) direction.

Hi there.

2nd try in explaining my problem.

I’m moving my spaceship forward in the mouse direction. (The below script is attached to the spaceship) When I press ‘L’ my ships turns the the nearest enemy. But when I move forward again (trying to move close to the nearest enemy) my ship immediately turns back to the position it left right before I pressed L. As explained in these drawings.


How does this happen? Is it because I work with 2 different Quaternion rotations? I can’t get my head around it. But it is probably very simple… I need to have it work like this:

See (full) script below:

 public class PlayerMovement : MonoBehaviour
    {
        [SerializeField] float movementSpeed = 35f;

    Transform t;
    private bool moveObject;

    public float mouseSensitivity = 100.0f;
    public float clampAngle = 80.0f;
    private float rotY = 0.0f;
    private float rotX = 0.0f;

    void Awake()
    {
        t = transform;
        moveObject = true;
        Vector3 rot = transform.localRotation.eulerAngles;
        rotY = rot.y;
        rotX = rot.x;
    }

    void Update()
    {
        Move();
        MousepointedMovement();

        if (Input.GetButtonDown("Vertical-"))
        {
            moveObject = true;
        }
    }

    void MousepointedMovement()
    {
        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = -Input.GetAxis("Mouse Y");

        rotY += mouseX * mouseSensitivity * Time.deltaTime;
        rotX += mouseY * mouseSensitivity * Time.deltaTime;

        rotX = Mathf.Clamp(rotX, -clampAngle, clampAngle);

        Quaternion localRotation = Quaternion.Euler(rotX, rotY, 0.0f);
        transform.rotation = localRotation;
    }

    void Move()
    {
        if (moveObject == true)
        {
            t.position += t.forward * movementSpeed * Time.deltaTime * Input.GetAxis("Vertical-");
        }
    }

    public void AutoTarget(Transform target)
    {
        if (Input.GetKeyDown(KeyCode.L))
        {
            moveObject = false;

            Vector3 relativePos = target.position - transform.position;
            Quaternion rotation = Quaternion.LookRotation(relativePos);
            transform.rotation = rotation;
        }
    }
}

It seems that you constantly update rotation with MousepointedMovement();
Even if you copy/paste code, try to comment lines and debug.log to understand what’s happening and when each function is called, it’s much faster than trying to explain your problem and waiting for response!

@yaourt , as I understand correctly, the main issue is that the Input.GetAxis("Mouse X") & Input.GetAxis("Mouse Y") do not change (when I autoTarget), so when those values stay the same, → the Quaternion localRotation = Quaternion.Euler(rotX, rotY, 0.0f); stays the same?

So when the script leads back to void MousepointedMovement() it still ‘thinks’ is has the correct (but old) information? Do I need to tell how much the object has rotated (when pressed L)?

Hope you can give me another hint to get me moving forward with this. THNX!

@yaourt , well I solved it, thanks to your help!

And like most of the times, and thankfully, it was very easy. But I couldn’t have seen it without your direction. I learned a lot.

It was actually just a matter of updating the float 'rotY' & 'rotX' after the autotarget rotation. That’s it.
Plus I implemented the mouse movement detection you mentioned and used it as a trigger to set mouseMovement to true after the auto-rotation.

Just in case it might be useful to someone ever visiting this question, here’s the updated script:

public class PlayerMovement : MonoBehaviour
{
    [SerializeField] float movementSpeed = 35f;

    Transform t;
    private bool moveObject = true;
    private bool mousePointing = true;

    public float mouseSensitivity = 100.0f;
    public float clampAngle = 80.0f;
    private float rotY = 0.0f;
    private float rotX = 0.0f;

    void Awake()
    {
        t = transform;

        Vector3 rot = transform.localRotation.eulerAngles;
        rotY = rot.y;
        rotX = rot.x;
    }
    void Update()
    {
        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = -Input.GetAxis("Mouse Y");

        rotY += mouseX * mouseSensitivity * Time.deltaTime;
        rotX += mouseY * mouseSensitivity * Time.deltaTime;

        rotX = Mathf.Clamp(rotX, -clampAngle, clampAngle);

        Move();

        MousepointedMovement();

        if (Input.GetAxis("Mouse X") < 0 || Input.GetAxis("Mouse X") > 0)
        {
            mousePointing = true;
        }

        if (Input.GetButtonDown("Vertical-"))
        {
            moveObject = true;
        }
    }

    void MousepointedMovement()
    {
        Quaternion localRotation = Quaternion.Euler(rotX, rotY, 0.0f);
        transform.rotation = localRotation;
    }

    void Move()
    {
        if (moveObject == true)
        {
            t.position += t.forward * movementSpeed * Time.deltaTime * Input.GetAxis("Vertical-");
        }
    }

    public void AutoTarget(Transform target)
    {
        if (Input.GetKeyDown(KeyCode.L))
        {
            moveObject = false;
            mousePointing = false;

            Vector3 relativePos = target.position - transform.position;
            Quaternion targetRotation = Quaternion.LookRotation(relativePos);
            transform.rotation = targetRotation;

            Vector3 floatingRotation = transform.localRotation.eulerAngles;
            rotY = floatingRotation.y;
            rotX = floatingRotation.x;

            if (transform.rotation == targetRotation)
            {
                mousePointing = true;
                moveObject = true;
            }
        }
    }
}