Unity3D简单实现游戏对象跟随鼠标旋转
代码实现
[SerializeField] LayerMask whatIsGround;
void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.Log(ray);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, 200, whatIsGround))
{
Vector3 target = hitInfo.point;
target.y = transform.position.y;
transform.LookAt(target);
}
}
代码解释
射线创建
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Camera.main
:用于获取第一个启用且被标记为 “MainCamera” 的相机。在 Unity 场景中,通常会有一个主相机负责渲染画面,通过Camera.main
可以方便地引用到这个相机。ScreenPointToRay(Input.mousePosition)
:该方法会从主相机射出一道无限延伸的射线,射线的起点是主相机的位置,方向指向鼠标当前在屏幕上的位置。Ray
类型包含两个重要的三维坐标属性:Origin
(原点)和Direction
(方向)。其中,Origin
会跟随鼠标的移动而改变,而Direction
始终是朝向主相机指向鼠标位置的方向。
射线碰撞检测
RaycastHit hitInfo;
RaycastHit
是一个结构体,它包含了射线与碰撞器发生碰撞时的相关信息。在这段代码中,我们主要使用其中的 point
属性,该属性表示射线与碰撞器碰撞点的世界坐标。
public static bool Raycast (Ray ray, out RaycastHit hitInfo, float maxDistance, int layerMask);
Physics.Raycast
是一个静态方法,用于检测射线是否与指定的遮罩层(layerMask
)的碰撞器产生碰撞。该方法返回一个布尔值,如果射线与指定遮罩层的碰撞器发生碰撞,则返回 true
,否则返回 false
。maxDistance
参数指定了射线的最大检测距离,这里设置为 200。
游戏对象旋转
transform.LookAt(target);
Transform.LookAt
方法用于让游戏对象的前向向量(通常是 Z 轴正方向)指向目标位置。在代码中,我们将 target
作为参数传递给 LookAt
方法,使得游戏对象朝向射线与地面碰撞点的位置。
可能遇到的问题及解决方法
问题描述
通过 Debug.Log()
输出 Ray
变量有数值,但是玩家不跟随鼠标移动而转向。
解决方法
可以通过 Debug.Log()
检查 Physics.Raycast()
返回的布尔值是否为 true
。如果返回值为 false
,则说明射线没有与指定遮罩层的碰撞器发生碰撞,此时需要检查场景内的地板 Layer
是否标记为对应的 layerMask
。例如,可以添加如下代码进行检查:
bool isHit = Physics.Raycast(ray, out hitInfo, 200, whatIsGround);
Debug.Log("Raycast result: " + isHit);
if (!isHit)
{
Debug.Log("Check the ground layer mask!");
}