描述
在xz平面中,玩家控制的物体时刻面朝鼠标的方向。
实现
首先需要将玩家(物体)的世界坐标转化为屏幕坐标。
Vector3 playerScreenPosition = Camera.main.WorldToScreenPoint(playerRigidbody.position);
然后获取鼠标的屏幕坐标。
Vector3 mousePosition = Input.mousePosition;
由于是只在xz屏幕移动,因此让鼠标的屏幕坐标z轴等于玩家的屏幕坐标的z轴。
mousePosition.z = playerScreenPosition.z;
将鼠标的屏幕坐标转换为世界坐标。
world = Camera.main.ScreenToWorldPoint(mousePosition);
使用LookAt控制玩家始终朝向鼠标方向。
playerRigidbody.transform.LookAt(world);
因此完整代码如下:
Vector3 playerScreenPosition = Camera.main.WorldToScreenPoint(playerRigidbody.position);
Vector3 mousePosition = Input.mousePosition;
mousePosition.z = playerScreenPosition.z;
world = Camera.main.ScreenToWorldPoint(mousePosition);
playerRigidbody.transform.LookAt(world);
分析
我们使用Input.mousePosition来获取鼠标的位置。下面是官方API中关于该方法的描述(自己翻译的,仅供参考):
Input.mousePosition
获得当前鼠标在像素坐标中的位置(Read Only)。
屏幕或窗口的左下方位于(0,0),屏幕或窗口的右上方位于(Screen.width,Screen.height)。
Input.mousePosition报告了鼠标的位置,即使鼠标不在游戏视图之中,例如当Cursor.lockState设置为CursorLockMode.None。当在窗口模式中且光标不受限制的话,位置的值小于0或者大于屏幕尺寸(Screen.width,Screen.height)表示鼠标在游戏窗口之外。
也就是说该方法返回的是鼠标的屏幕坐标,接下来我们需要了解一下屏幕坐标和世界坐标。
屏幕坐标是指通过主摄像机将物体投射在屏幕上的坐标,是以像素为单位定义的,左下方是(0,0),右上角是(pixelWidth,pixelHeight),z轴在相对于相机的世界单位中。
世界坐标是一个物体真实坐标,即为三维的坐标。
也就是说我们要把鼠标的屏幕坐标转换为世界坐标。而我们要求物体必须在xz平面运动,不能在y轴运动,因此我们需要提前赋予鼠标的屏幕坐标z轴一个值,该值应该和玩家转换为屏幕坐标后的z轴值相等。于是我们需要用Camera.WorldToScreenPoint来将玩家的世界坐标转换为屏幕坐标,然后令mousePosition.z = playerScreenPosition.z,再将屏幕坐标转换为世界坐标,令玩家LookAt该坐标即可。