Move object perpendicular to the mouse position

In my code I have the player moving towards the mouse position when I press W and from the mouse position when pressing S. I also want the player to move left and right when I press A and D. However, I don’t want the player to move left and right according to the X and Y-plane but relative to where the player is to the mouse position (the player rotates towards the mouse position at all times). So basically, when the player is rotated I want it to move perpendicular to it’s direction to the mouse position when I press A or D.

This is my code for moving to/from the mouse:

     void Update()
        {
            if (Input.GetKey(KeyCode.W))
            {
                target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                target.z = transform.position.z;
                transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime);
            }
            if (Input.GetKey(KeyCode.S))
            {
                target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                target.z = transform.position.z;
                transform.position = Vector3.MoveTowards(transform.position, target, -speed * Time.deltaTime);
            }
        }

It also rotates using the following code:

    void Update()
        {
            //rotation
            Vector3 mousePos = Input.mousePosition;
            mousePos.z = 0;
  
            Vector3 objectPos = Camera.main.WorldToScreenPoint(transform.position);
            mousePos.x = mousePos.x - objectPos.x;
            mousePos.y = mousePos.y - objectPos.y;
  
            float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
            angle -= 90;
            transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
            }
        }

Calculate the Vector3 from the player to the mouse and then the perpendicular vector. Following code is not tested but should be something like this:

When pressing the left/right keys you have to move either along the “move” vector or the opposite direction.
Hope it helps

It’s missing a negation.
Either clockwise:

Vector3 perp = new Vector3(objectPos.y, -objectPos.x, 0);

Or counter-clockwise

Vector3 perp = new Vector3(-objectPos.y, objectPos.x, 0);

It’s not really working. I think you made a mistake to begin with, since you never actually calculate the vector between the mouse and the object’s position. I redid the code a bit and got this:

Vector3 mousePos = Input.mousePosition;
        mousePos.z = 0;
        Vector3 objectPos = Camera.main.WorldToScreenPoint(transform.position);
        Vector3 n1 = mousePos - objectPos;
        Vector3 perp = new Vector3(n1.y, n1.x, 0);

and then:

if (Input.GetKey(KeyCode.A))
        {
            transform.position = Vector3.MoveTowards(transform.position, -perp, speed * Time.deltaTime);
        }
        else if (Input.GetKey(KeyCode.D))
        {
            transform.position = Vector3.MoveTowards(transform.position, perp, speed * Time.deltaTime);
        }

It works as long as the player is moving along the x and y-axis. However, if I’m moving 45 degrees (my player always follows the mouse position) it’s not working. Then the player just continues to walk towards/from the mouse if I press A or D.

You also forgot what I had mentioned above. You have to not only switch, but also invert either the x or the y value.

I’ve written a quick example, which at least uses the correct perpendicular (clockwise) vector on a per-frame basis. If you want to eliminate the “rotate around” effect when you move sideways , you can do that of course.

using UnityEngine;

public class CLASS_NAME : MonoBehaviour
{
    private Camera _mainCamera;

    [SerializeField]
    private float speed = 2f;

    private void Awake()
    {
        _mainCamera = Camera.main;
    }

    private void Update()
    {
        var mouseWorldPosition = _mainCamera.ScreenToWorldPoint(Input.mousePosition);
        mouseWorldPosition.z = 0f; // this should actually be transform.position.z in case your sprite is not located at z = 0
        // this is one way to rotate, right (x-axis) being the new forward
        transform.right = (mouseWorldPosition - transform.position);
   
        var movementVector = GetMovementVector();
        transform.Translate(movementVector * Time.deltaTime * speed);
    }

    private Vector2 GetMovementVector()
    {
        Vector2 movementDirection = Vector2.zero;
    
        // accumulates the input, use else if to only enable one key at a time
        if (Input.GetKey(KeyCode.A))
        {
            movementDirection.y -= 1f;
        }
        if (Input.GetKey(KeyCode.D))
        {
            movementDirection.y += 1f;
        }
        if (Input.GetKey(KeyCode.W))
        {
            movementDirection.x += 1f;
        }
        if (Input.GetKey(KeyCode.S))
        {
            movementDirection.x -= 1f;
        }
   
        return movementDirection.normalized;
    }
}

Yes you are right :slight_smile: I wrote it a bit in a hurry (sorry).

Wasn’t meant to be offending in any way. So there’s no reason to say sorry :slight_smile: Don’t worry, we’re all kind persons. :slight_smile:

I didn’t take it that way. Glad you got it working :slight_smile: