首页 > 解决方案 > 如何根据我当前的世界鼠标位置 3D 旋转我的播放器(等距视角)

问题描述

这个游戏是 3d 的,但视图是“正交的”,请参阅下图以获得更清晰的视角

插图

我正在尝试将玩家的旋转设置为始终面向游戏世界中的鼠标位置,但仅围绕 Y 旋转轴旋转玩家。

我的伪代码是这样的:

见:插图

标签: c#unity3drotation

解决方案


从您的伪代码开始,您只需查看 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);
        }
    }
}

推荐阅读