SmogTownRat
SmogTownRat

Reputation: 1

How do I rotate my player based on my current world mouse position 3D (isometric-like viewing angle)

This game is 3d, but the view is 'orthographic-like' please see the illustration below for more clarity on viewing angle

illustration

I'm trying to set my player's rotation to always face the mouse position in the game world, but only rotating the player around the Y rotational axis.

My pseudocode is something like:

see: illustration

Upvotes: 0

Views: 1900

Answers (2)

derHugo
derHugo

Reputation: 90862

Starting from your pseudo code you could find some of these by simply looking into the API:

  • get mouse pos on screen.

Unity already provides this: Input.mousePosition

  • get player pos in world.

Once you have a reference to the according GameObject or better directly Transform you can simply access its position

  • convert mouse pos on screen to mouse pos in world.

There are multiple solutions like Camera.ScreenToWorldPoint. In this case however it would be easier to create a mathematical Plane and then use Camera.ScreenPointToRay in order to get a ray for your mouse and pass it into Plane.Raycast.

  • determine distance from mouse pos to player pos.
  • use atan2 on x, z to calculate angle.
  • use angle to continually adjust player rotation to mouse pos

These are not necessary since Unity already does all of this for you ;)

Instead you can simply calculate the vector direction from your player to the point where the mouse ray hits the plane, erase the difference in the Y axis and the use Quaternion.LookRotation in order to rotate the player to make it look into the same direction.

So it could look like e.g.

// drag in your player object here via the Inspector
[SerializeField] private Transform _player;

// If possible already drag your camera in here via the Inspector
[SerializeField] private Camera _camera;

private Plane plane;

void Start()
{
    // create a mathematical plane where the ground would be
    // e.g. laying flat in XZ axis and at Y=0
    // if your ground is placed differently you'ld have to adjust this here
    plane = new Plane(Vector3.up, Vector3.zero);

    // as a fallback use the main camera
    if(!_camera) _camera = Camera.main;
}

void Update()
{
    // Only rotate player while mouse is pressed
    // change/remove this according to your needs
    if (Input.GetMouseButton(0))
    {
        //Create a ray from the Mouse position into the scene
        var ray = _camera.ScreenPointToRay(Input.mousePosition);

        // Use this ray to Raycast against the mathematical floor plane
        // "enter" will be a float holding the distance from the camera 
        // to the point where the ray hit the plane
        if (plane.Raycast(ray, out var enter))
        {
            //Get the 3D world point where the ray hit the plane
            var hitPoint = ray.GetPoint(enter);

            // project the player position onto the plane so you get the position
            // only in XZ and can directly compare it to the mouse ray hit
            // without any difference in the Y axis
            var playerPositionOnPlane = plane.ClosestPointOnPlane(_player.position);

            // now there are multiple options but you could simply rotate the player so it faces 
            // the same direction as the one from the playerPositionOnPlane -> hitPoint 
            _player.rotation = Quaternion.LookRotation(hitPoint-playerPositionOnPlane);
        }
    }
}

Upvotes: 2

I suggest you two ways: 1) Use a raycast, which hits your surface where character stands, something like ScreePointToRay. Get the "hit" from ray and rotate your character to hit point, counting angle between character pos and hit point. 2) Convert character pos to screen point with Camera.WorldToScreenPoint and after that count angle between mouse point and character point. After that you will know angle between them.

Be aware of function called LookAt, maybe it will be handy.

Upvotes: 0

Related Questions