原标题:[蛮牛驿馆] Unity2D:用射线检测物体的点击
通常,在Unity里会经常使用OnMouseDown检测GameObjects上的点击。效果很好,但需要在Gameobject上挂一个脚本,而且当存在很多可点击的物体时还必须要同步。
另一种方法,也就是这边文章要讲到的,就是用一个脚本来管理整个游戏中的点击。一大堆的理由可以说明这是非常有用的,但主要是提供一个集中的位置来管理所有的输入以及整合整个游戏过程中的点击。举个例子,在角色的视野范围内时,在菜单关闭时,或者没有游戏内的对话框弹出时,可能只有一个Box可以被点击。在这种情况下,将点击的逻辑放在Box的脚本里,需要box有知识来访问角色、菜单和对话框系统,这样就会导致混乱的代码。在GameObjects里挂上点击事件还会导致一个
问题
,假如要支持多种输入,比如点击和触摸,你会发现有太多的GameObject的脚本都挂上了点击事件,而且还没达到本身的目的。
就因为上边提到的两个原因,我更偏向于用一个单一的输入脚本来管理这些点击事件以及代理被点击的物体。这样一来,当点击/触摸事件发生时,只需要简单地通知与交互相关的GameObject即可,而不用关心输入的是什么,只是有输入就行。为了实现这个设想,创建一个空GameObject,命名为Click Manger,挂上一个脚本。脚本就叫ClickManger。
监听点击事件
在ClickManger脚本里,用Update函数检测鼠标是否已经点击:
我们用的是Input.GetMouseButtonDown来检测是否鼠标左键(0代表左键)在当前帧被按下。也就是说,当你点击时,即使一直按着鼠标左键不放,在Update函数的循环中也仅仅返回一次true,直到释放鼠标并再次点击。对于鼠标右键用1代表,鼠标中间则是用2代表。
什么被点击了呢?
既然知道了点击已经发生,但是我们怎么知道具体什么被点击到了呢?因为这个脚本并不属于游戏中是实际物体(仅仅是一个空物体)我们需要用Raycast来检测到底用户点击了什么。
Raycast的实质就是在游戏场景中的两点之间“画”了一条线,检测这条线上碰撞到的任何物理物体。你就可以用碰撞获得的信息来确定碰撞到的物体并做相应处理。另一个Raycast比较有用的样例
有一件事情值得注意:点击的位置指的是屏幕坐标,而不是世界坐标。屏幕坐标代表像素,(0,0)点是指屏幕左下角。我们需要将屏幕坐标转换成世界坐标以正确地与场景中的GameObjects做匹配。另外一个小问题是,点击的位置包含了Z轴的坐标,在
2D
游戏中是不相干的,但还是会干涉到Raycast的检测,因为Z轴在2D游戏中依然是存在的,所以,我们需要忽略Z轴。
首先,在if语句中,将点击坐标转换成世界坐标:
用ScreenToWorldPoint将Input.mousePosition转换成世界坐标,这样就可以用来与GameObject相比较了。
接下来,我们用Physics2D.Raycast生成射线,提供一个Vector2类型的mousePos忽略Z轴作为起始点。还要提供一个Vector2.zero作为Raycast的方向以保证只有在点击方向的位置上的物体才可以被检测到:
现在可以用Raycast2D来确定是否有物体被点击了:
Hit.collider返回一个Collider2D,从这个Collider2D中可以访问到点击到物体的Rigibody和GameObject属性。现在我们就可以直接操作被点击到的物体!在接下来的例子中,我们只是简单地打印被点击到的物体的名字,给rigibody施加一个作用力:
按照游戏交互设计,因为你已经知道哪个物体已经被点击到了并且怎样获取该物体,你可以对被点击的物体做任何处理。愉快地点吧!
返回搜狐,查看更多
责任编辑:
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。