[3D] Top-Down Make Character move in the direction of the position he is currently looking at?


This is my first post here, i saw this forums are very active and i hope im getting help here. I was spending a few rages with one simple thing which i finished now thanks to google and tutorials and my brain which actually works sometimes. But now i have something i can’t find in the internet so far.

  1. I started making a 3D Top-Down Shooter and did the code to move the character like normal with WASD and make him look in the direction of the mouse cursor. It works, but he is just looking at the mouse cursors position. When i hold down W he walks straight forward and still looks to the position. I want him to when i press W also start rotating, so walking in the direction of the mouse cursor.

And like in other 3D Top Down Games when i press W/A/S/D he should walk to the forward (for example) in the direction of his current viewing position, so for example, if he is viewing to the right side of the screen and i press D, he should walk to the right of him so in this case to the screen bottom then because his right side is pointing to the bottom. Currently for me, when he is looking to the right side and i’d press D for example, he would walk to the right side of the screen, not to the right side of his eyes position.

This is the current C# Code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour

    public float moveSpeed;
    private Rigidbody myRigidbody;

    private Vector3 moveInput;
    private Vector3 moveVelocity;

    private Camera mainCamera;

    // Start is called before the first frame update
    void Start()
        myRigidbody = GetComponent<Rigidbody>();
        mainCamera = FindObjectOfType<Camera>();

    // Update is called once per frame
    void Update()
        moveInput = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical"));
        moveVelocity = moveInput * moveSpeed;

        Ray cameraRay = mainCamera.ScreenPointToRay(Input.mousePosition);
        Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
        float rayLength;

        if (groundPlane.Raycast(cameraRay, out rayLength))
            Vector3 pointToLook = cameraRay.GetPoint(rayLength);
            Debug.DrawLine(cameraRay.origin, pointToLook, Color.blue);

            transform.LookAt(new Vector3(pointToLook.x, transform.position.y, pointToLook.z));

    private void FixedUpdate()
        myRigidbody.velocity = moveVelocity;

So what do i need to write / change? Can you give me the code maybe? I dont have C# knowledges, i can understand and read some code but don’t write at all.

Sorry for my very bad english, i hope you understand me :confused:

You need to rotate the velocity to take into account the characters rotation. I haven’t tested this transformation but you could try and see the results.

 private void FixedUpdate()
     //get the angle between positive Z axis and character facing
     float characterAngle = Vector3.Angle(Vector3.forward, transform.forward);
     //make a quaternion representing the rotation of such angle
     Quaternion rotation = Quaternion.AngleAxis(characterAngle , Vector3.up);
     //rotate velocity vector by said rotation
     myRigidbody.velocity = rotation * moveVelocity;

@Tsaras was close. Just swap out Vector3.Angle with Vector3.SignedAngle and it works like a charm. You have to add an axis to it though.

         float characterAngle = Vector3.SignedAngle(Vector3.forward, transform.forward, Vector3.up);
        Quaternion rotation = Quaternion.AngleAxis(characterAngle, Vector3.up);
        rb.velocity = rotation * moveVelocity;

Thanks @Tsaras for answering the initial question!