NemoPS
NemoPS

Reputation: 411

Unity 3d, point object towards mouse (3d space)

I searched around for a while but I couldn't figure out how to solve this nasty bug. I am using a top down view (pointing towards -z), basically 2d with 3d objects and camera in perspective mode.

I need to orient an object towards the mouse , ignoring the z aspect, as everything moves on the same plane.

I am using the following code:

 Vector3 mouseToWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition + new Vector3(0, 0, 1f));
 mouseToWorld.z = 0f;
 Vector3 difference = mouseToWorld - transform.position;
 difference.Normalize();
 float angle = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
 transform.rotation = Quaternion.Euler(0f, 0f, angle - 90);

Unfortunately it only works when the object is still, and breaks as soon as the velocity is > 0;

Any hint would be appreciated :)

p.s. I am adding 1 to the z and then resetting it, because otherwise the mouseToWorld is constantly 0 wherever I move the pointer.

Upvotes: 0

Views: 2048

Answers (2)

NemoPS
NemoPS

Reputation: 411

Thanks for the answer! I figured out you need to subtract the distance between the player and the camera to the initial mouse position:

Vector3 mouseToWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition - new Vector3(0, 0, Camera.main.transform.position.z));

Here the working script:

    Vector3 mouseToWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition - new Vector3(0, 0, Camera.main.transform.position.z));
    //Debug.DrawLine(transform.position, mouseToWorld);
    mouseToWorld.z = 0f;
    Vector3 difference = mouseToWorld - transform.position;
    difference.Normalize();

    float angle = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
    transform.rotation = Quaternion.Euler(0f, 0f, angle - 90);

Upvotes: 0

LonelyDaoist
LonelyDaoist

Reputation: 714

Perhaps it breaks because the velocity vector and the mouse direction aren't the same.

the following script will make an arrow follow the mouse, It's basically the same as yours except it updates the position as well:

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

public class FollowMouse : MonoBehaviour {
    public float moveSpeed = 0.01f;
    // Use this for initialization
    void Start () {
    }

  // Update is called once per frame
  void Update () {
        transform.position = Vector2.Lerp(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), moveSpeed);

        Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
        difference.Normalize();
        float rotation_z = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
        transform.rotation = Quaternion.Euler(0f, 0f, rotation_z);
    }
}

Upvotes: 1

Related Questions