c# - 如何根据我当前的世界鼠标位置 3D 旋转我的播放器(等距视角)
问题描述
这个游戏是 3d 的,但视图是“正交的”,请参阅下图以获得更清晰的视角
我正在尝试将玩家的旋转设置为始终面向游戏世界中的鼠标位置,但仅围绕 Y 旋转轴旋转玩家。
我的伪代码是这样的:
- 在屏幕上获取鼠标位置。
- 在世界中获得玩家位置。
- 将屏幕上的鼠标位置转换为世界上的鼠标位置。
- 确定从鼠标位置到玩家位置的距离。
- 在 x, z 上使用 atan2 来计算角度。
- 使用角度不断调整玩家旋转到鼠标位置。
见:插图
解决方案
从您的伪代码开始,您只需查看 API 即可找到其中的一些:
- 在屏幕上获取鼠标位置。
Unity 已经提供了这个:Input.mousePosition
- 在世界中获得玩家位置。
一旦您直接参考了相应的GameObject
或更好的,Transform
您就可以简单地访问它position
- 将屏幕上的鼠标位置转换为世界上的鼠标位置。
有多种解决方案,例如Camera.ScreenToWorldPoint
. Plane
然而,在这种情况下,创建一个数学然后使用它会更容易Camera.ScreenPointToRay
为您的鼠标获取射线并将其传递到Plane.Raycast
.
- 确定从鼠标位置到玩家位置的距离。
- 在 x, z 上使用 atan2 来计算角度。
- 使用角度不断调整玩家旋转到鼠标位置
这些都不是必需的,因为 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);
}
}
}
推荐阅读
- java - 如何让 Emoji 在 Mac OS 上的 Java Swing 小部件中呈现?
- autohotkey - 将一个函数的输出作为参数传递给另一个函数
- node.js - FetchError:对 https://discord.com/api/v7/gateway/bot 的请求失败,原因:无法获取本地颁发者证书
- php - 新创建的 PHP Codeception 项目正在运行,没有错误输出
- ruby - 有没有办法在不使用 3 个收集器来组合字符串的情况下重构它?
- excel - 在 Excel 上创建一组合并的对
- python - 使用迭代器创建正则表达式模式
- responsive-design - CSS 打破媒体内容而不是屏幕大小
- clickhouse - Clickhouse:滑动/移动窗口
- jq - jq + 运算符是否渴望?