【发布时间】:2020-05-18 07:10:17
【问题描述】:
这个游戏是 3d 的,但视图是“正交的”,请参阅下图以更清楚地了解视角
我正在尝试将玩家的旋转设置为始终面向游戏世界中的鼠标位置,但仅围绕 Y 旋转轴旋转玩家。
我的伪代码是这样的:
- 在屏幕上获取鼠标位置。
- 获取玩家在世界中的位置。
- 将屏幕上的鼠标位置转换为世界上的鼠标位置。
- 确定鼠标位置到玩家位置的距离。
- 在 x、z 上使用 atan2 来计算角度。
- 使用角度不断调整玩家旋转到鼠标位置。
【问题讨论】:
这个游戏是 3d 的,但视图是“正交的”,请参阅下图以更清楚地了解视角
我正在尝试将玩家的旋转设置为始终面向游戏世界中的鼠标位置,但仅围绕 Y 旋转轴旋转玩家。
我的伪代码是这样的:
【问题讨论】:
我建议你两种方式: 1) 使用光线投射,投射到角色站立的表面,例如 ScreePointToRay。从射线中获取“命中”并将您的角色旋转到命中点,计算角色位置和命中点之间的角度。 2)使用Camera.WorldToScreenPoint将字符位置转换为屏幕点,然后计算鼠标点和字符点之间的角度。之后你就会知道它们之间的角度。
注意一个叫做 LookAt 的函数,也许它会很方便。
【讨论】:
从您的伪代码开始,您只需查看 API 即可找到其中的一些:
Unity 已经提供了这个:Input.mousePosition
一旦您引用了GameObject 或更好的直接Transform,您就可以简单地访问它的position
有多种解决方案,例如Camera.ScreenToWorldPoint。然而,在这种情况下,创建一个数学Plane 然后使用Camera.ScreenPointToRay 来为您的鼠标获取光线并将其传递给Plane.Raycast 会更容易。
这些不是必需的,因为 Unity 已经为您完成了所有这些;)
相反,您可以简单地计算从您的播放器到鼠标射线撞击平面的点的矢量方向,消除Y 轴上的差异并使用Quaternion.LookRotation 以旋转播放器使其看起来同一个方向。
所以它可能看起来像例如
// 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);
}
}
}
【讨论】: