我们在项目中常常会有点击屏幕中的物体后实现打开UI菜单、高亮等功能的需求,下面我盘点了两种常用的方法。
射线检测
- 在任意进入场景会被加载的脚本,如玩家角色中的脚本中加入创建发射射线的函数(最好是单例的脚本,不然函数有可能会被多次执行)
-
private RaycastHit CastRay() { Vector3 screenFar = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.farClipPlane); Vector3 screenNear = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane); Vector3 far = Camera.main.ScreenToWorldPoint(screenFar); Vector3 near = Camera.main.ScreenToWorldPoint(screenNear); RaycastHit hit; Physics.Raycast(near, far - near, out hit); return hit; }
- screenFar和screenNear分别获取鼠标点击的xy坐标,以及MainCamera的最远剪切面和最近剪切面,不让射线无限延长
- 使用ScreenToWorldPoint()将z轴(深度)的距离转换为场景空间的坐标点
- Raycast()的参数分别为射线的起点,方向,碰撞物信息
-
- 在Update()中编写以下代码,当用户按左键时,如果射线检测到了物体则返回else中的信息
-
void Update () { if (Input.GetMouseButtonDown(0)) { RaycastHit hit = CastRay(); if (!hit.collider) { return; } else { //测试,输出被交互的物体,可以再次编写其他逻辑 Debug.LogWarning("被射线检测的物体名:" + hit.collider.gameObject.name); } } }
-
OnMouseDown()
- 在需要被交互的物体中加入collider
- 在需要被交互的物体中编写脚本,脚本中加入函数OnMouseDown()编写交互后的逻辑
- 当用户按左键时,如果左键指向绑定该脚本的物体则执行下面代码
private void OnMouseDown()
{
//测试,输出被交互的物体,可以再次编写其他逻辑
Debug.LogWarning("被射线检测的物体名:" + gameObject.name);
}
参考资料
https://www.bilibili.com/video/BV1R3411W73E
https://docs.unity3d.com/cn/current/ScriptReference/MonoBehaviour.OnMouseDown.html