【问题标题】:Unity - Find a point for a gameobject to look at the mouse while camera is at any angleUnity - 在相机处于任何角度时为游戏对象找到一个看鼠标的点
【发布时间】:2016-02-23 20:36:37
【问题描述】:

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

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

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

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

我当前的代码是:

        // 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);
        }
     }

【问题讨论】:

  • 看看this answer
  • 为什么不直接使用 LookAt ????????????请注意,通常永远不要使用四元数。只需使用旋转。这是 Unity 中的一大困惑。
  • @JoeBlow 这不是重复的。我意识到我的问题的标题并不是最好的,但是现在它已经改变了,即使只看图片就可以理解问题也没关系。感谢您提供关于不使用四元数的意见。

标签: math unity3d camera rotation


【解决方案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

您可以在Unity - Plane 文档页面上找到有关Plane 类的更多信息。

【讨论】:

  • 你又一次在 MotoSV 的问题上救了我,TY! Plane 解决方案非常简单和干净,它允许我使用其他内置函数,例如 LookAt(),所以我不必进入任何三角函数。
猜你喜欢
  • 2020-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
相关资源
最近更新 更多