Unity - 找到一个点让游戏对象在相机处于任何角度时看着鼠标
Unity - Find a point for a gameobject to look at the mouse while camera is at any angle
我有一个 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 and/or 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);
}
}
虽然这不能直接回答您关于 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);
}
}
基本思路是:
- 创建一个以游戏对象位置为中心的
Plane
实例
- 将鼠标屏幕位置转换成
Ray
进入世界
相对于相机的当前位置和旋转
- 然后将该光线投射到在步骤 #1
中创建的 Plane
- 如果射线与平面相交,则可以使用
GetPoint
方法找出射线在平面上的哪个位置
- 然后创建一个从平面中心到交点的方向向量,并根据向量
创建一个LookRotation
您可以在 Unity - Plane 文档页面上找到有关 Plane
class 的更多信息。
我有一个 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 and/or 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);
}
}
虽然这不能直接回答您关于 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);
}
}
基本思路是:
- 创建一个以游戏对象位置为中心的
Plane
实例 - 将鼠标屏幕位置转换成
Ray
进入世界 相对于相机的当前位置和旋转 - 然后将该光线投射到在步骤 #1 中创建的
- 如果射线与平面相交,则可以使用
GetPoint
方法找出射线在平面上的哪个位置 - 然后创建一个从平面中心到交点的方向向量,并根据向量 创建一个
Plane
LookRotation
您可以在 Unity - Plane 文档页面上找到有关 Plane
class 的更多信息。