Unity - 在摄像头处于任何角度时,找一个游戏对象观察鼠标的点

时间:2016-02-23 05:49:33

标签: math unity3d camera rotation

我有一个3D游戏,我希望箭头指向基于2D视图中该对象的鼠标角度的方向。

现在,相机从90度x角度俯视电路板,它可以正常工作。下面的图像是当我在我的游戏中面向下90度x角度相机角度时,我的光标所在的箭头面是:

enter image description here

但是现在当我们向后退一步并使相机处于45度x角时,箭头所朝向的方向有点偏离。下面的图像是当我的相机处于45度x角度时光标面向我的鼠标光标时:

enter image description here

现在让我们看看上面的图像,但是当相机移回90度x角时:

enter image description here

我目前的代码是:

        // Get the vectors of the 2 points, the pivot point which is the ball start and the position of the mouse.
        Vector2 objectPoint = Camera.main.WorldToScreenPoint(_arrowTransform.position);
        Vector2 mousePoint = (Vector2)Input.mousePosition;
        float angle = Mathf.Atan2( mousePoint.y - objectPoint.y, mousePoint.x - objectPoint.x ) * 180 / Mathf.PI;
        _arrowTransform.rotation = Quaternion.AngleAxis(-angle, Vector2.up) * Quaternion.Euler(90f, 0f, 0f);

我需要在Mathf.Atan2()中添加什么来补偿x和/或y上的相机旋转,以确保当用户想要移动相机时如何取悦它将确保提供准确的方向?

编辑:解决方案是在MotoSV的回答中使用Plane。无论我的摄像机角度是基于我的鼠标位置,这都让我得到了确切的点。对我有用的代码如下:

    void Update()
    {
        Plane groundPlane = new Plane(Vector3.up, new Vector3(_arrowTransform.position.x, _arrowTransform.position.y, _arrowTransform.position.z));
        Ray ray = _mainCamera.ScreenPointToRay(Input.mousePosition);
        float distance;
        if (groundPlane.Raycast(ray, out distance))
        {
            Vector3 point = ray.GetPoint(distance);
            _arrowTransform.LookAt(point);
        }
     }

1 个答案:

答案 0 :(得分:1)

虽然这不会直接回答您关于Mathf.Atan2方法的问题,但它是一种可能有用的替代方法。

这将被放置在代表箭头的游戏对象上:

public class MouseController : MonoBehaviour
{
    private Camera _camera;

    private void Start()
    {
        _camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>();
    }

    private void Update()
    {
        Plane groundPlane = new Plane(Vector3.up, this.transform.position);
        Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
        float distance;
        Vector3 axis = Vector3.zero;

        if(groundPlane.Raycast(ray, out distance))
        {
            Vector3 point = ray.GetPoint(distance);
            axis = (point - this.transform.position).normalized;
            axis = new Vector3(axis.x, 0f, axis.z);
        }

        this.transform.rotation = Quaternion.LookRotation(axis);
    }
}

基本思路是:

  1. 创建以游戏对象位置为中心的Plane实例
  2. 将鼠标屏幕位置转换为前往世界的Ray 相对于相机的当前位置和旋转
  3. 然后将该光线投射到步骤#1中创建的Plane
  4. 如果光线与平面相交,那么您可以使用GetPoint方法找出光线在平面上的位置
  5. 然后创建从平面中心到交叉点的方向向量,并根据向量创建LookRotation
  6. 您可以在Unity - Plane文档页面上找到有关Plane课程的更多信息。