开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

蛮牛译馆

关注:553

当前位置:游戏蛮牛 技术专区 蛮牛译馆

查看: 793|回复: 8

[外文翻译] Unity2D:用射线检测物体的点击

[复制链接]  [移动端链接]
排名
20829
昨日变化
20

21

主题

105

帖子

340

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
156801
好友
2
蛮牛币
560
威望
0
注册时间
2016-7-15
在线时间
167 小时
最后登录
2017-8-17
发表于 2017-7-24 16:28:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 204有个大坑 于 2017-7-24 16:28 编辑

      通常,在Unity里会经常使用OnMouseDown检测GameObjects上的点击。效果很好,但需要在Gameobject上挂一个脚本,而且当存在很多可点击的物体时还必须要同步。
      另一种方法,也就是这边文章要讲到的,就是用一个脚本来管理整个游戏中的点击。一大堆的理由可以说明这是非常有用的,但主要是提供一个集中的位置来管理所有的输入以及整合整个游戏过程中的点击。举个例子,在角色的视野范围内时,在菜单关闭时,或者没有游戏内的对话框弹出时,可能只有一个Box可以被点击。在这种情况下,将点击的逻辑放在Box的脚本里,需要box有知识来访问角色、菜单和对话框系统,这样就会导致混乱的代码。在GameObjects里挂上点击事件还会导致一个问题,假如要支持多种输入,比如点击和触摸,你会发现有太多的GameObject的脚本都挂上了点击事件,而且还没达到本身的目的。
     就因为上边提到的两个原因,我更偏向于用一个单一的输入脚本来管理这些点击事件以及代理被点击的物体。这样一来,当点击/触摸事件发生时,只需要简单地通知与交互相关的GameObject即可,而不用关心输入的是什么,只是有输入就行。为了实现这个设想,创建一个空GameObject,命名为Click Manger,挂上一个脚本。脚本就叫ClickManger。
unity-click-raycast-1.png

监听点击事件
在ClickManger脚本里,用Update函数检测鼠标是否已经点击:
[C#] 纯文本查看 复制代码
using UnityEngine;using System.Collections;
public class ClickManager : MonoBehaviour {

        void Update () {
                if (Input.GetMouseButtonDown(0)) {
                        Debug.Log("Mouse Clicked");
                }
        }
}


      我们用的是Input.GetMouseButtonDown来检测是否鼠标左键(0代表左键)在当前帧被按下。也就是说,当你点击时,即使一直按着鼠标左键不放,在Update函数的循环中也仅仅返回一次true,直到释放鼠标并再次点击。对于鼠标右键用1代表,鼠标中间则是用2代表。
什么被点击了呢?
      既然知道了点击已经发生,但是我们怎么知道具体什么被点击到了呢?因为这个脚本并不属于游戏中是实际物体(仅仅是一个空物体)我们需要用Raycast来检测到底用户点击了什么。

Raycast的实质就是在游戏场景中的两点之间“画”了一条线,检测这条线上碰撞到的任何物理物体。你就可以用碰撞获得的信息来确定碰撞到的物体并做相应处理。另一个Raycast比较有用的样例,请看我的另一篇文章 https://kylewbanks.com/blog/unity--checking-if-a-character-or-object-is-on-the-ground-using-raycasts(我也翻译了,翻译在此 http://www.manew.com/thread-102172-1-1.html

有一件事情值得注意:点击的位置指的是屏幕坐标,而不是世界坐标。屏幕坐标代表像素,(0,0)点是指屏幕左下角。我们需要将屏幕坐标转换成世界坐标以正确地与场景中的GameObjects做匹配。另外一个小问题是,点击的位置包含了Z轴的坐标,在2D游戏中是不相干的,但还是会干涉到Raycast的检测,因为Z轴在2D游戏中依然是存在的,所以,我们需要忽略Z轴。
首先,在if语句中,将点击坐标转换成世界坐标:
[C#] 纯文本查看 复制代码
if (Input.GetMouseButtonDown(0)) {
    Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);}


用ScreenToWorldPoint将Input.mousePosition转换成世界坐标,这样就可以用来与GameObject相比较了。
接下来,我们用Physics2D.Raycast生成射线,提供一个Vector2类型的mousePos忽略Z轴作为起始点。还要提供一个Vector2.zero作为Raycast的方向以保证只有在点击方向的位置上的物体才可以被检测到:

[C#] 纯文本查看 复制代码
if (Input.GetMouseButtonDown(0)) {
    Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    Vector2 mousePos2D = new Vector2(mousePos.x, mousePos.y);

    RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero);}


现在可以用Raycast2D来确定是否有物体被点击了:
[C#] 纯文本查看 复制代码
if (hit.collider != null) {
    Debug.Log("Something was clicked!");}


Hit.collider返回一个Collider2D,从这个Collider2D中可以访问到点击到物体的Rigibody和GameObject属性。现在我们就可以直接操作被点击到的物体!在接下来的例子中,我们只是简单地打印被点击到的物体的名字,给rigibody施加一个作用力:

[C#] 纯文本查看 复制代码
if (hit.collider != null) {
    Debug.Log(hit.collider.gameObject.name);
    hit.collider.attachedRigidbody.AddForce(Vector2.up);}


按照游戏交互设计,因为你已经知道哪个物体已经被点击到了并且怎样获取该物体,你可以对被点击的物体做任何处理。愉快地点吧!
全部脚本
[C#] 纯文本查看 复制代码
using UnityEngine;using System.Collections;
public class ClickManager : MonoBehaviour {

    void Update () {
        if (Input.GetMouseButtonDown(0)) {
            Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            Vector2 mousePos2D = new Vector2(mousePos.x, mousePos.y);
            
            RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero);
            if (hit.collider != null) {
                Debug.Log(hit.collider.gameObject.name);
                hit.collider.attachedRigidbody.AddForce(Vector2.up);
            }
        }
    }
}


原文作者:Written by @kylewbanks
原文连接:https://kylewbanks.com/blog/unity-2d-detecting-gameobject-clicks-using-raycasts

扫描下方二维码关注游戏蛮牛官方微信~每日都有精选干货与你分享哟~

本文由蛮牛译馆倾情奉献,翻译:204有个大坑,如果问题请及时联系,除合作社区及合作媒体外,禁止转载。

155547iluo7umxezrb2ekr.png

回复

使用道具 举报

5熟悉之中
793/1000
排名
4713
昨日变化
43

0

主题

420

帖子

793

积分

Rank: 5Rank: 5

UID
156480
好友
0
蛮牛币
1249
威望
0
注册时间
2016-7-12
在线时间
149 小时
最后登录
2017-8-17
发表于 2017-7-28 09:35:58 | 显示全部楼层
666666666666

回复

使用道具 举报

排名
26821
昨日变化
27

0

主题

17

帖子

43

积分

Rank: 1

UID
146147
好友
0
蛮牛币
93
威望
0
注册时间
2016-4-20
在线时间
18 小时
最后登录
2017-7-31
发表于 2017-7-31 16:01:24 | 显示全部楼层
谢谢分享,666

回复

使用道具 举报

7日久生情
4996/5000
排名
251
昨日变化

0

主题

2313

帖子

4996

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
3215
好友
0
蛮牛币
290
威望
0
注册时间
2013-9-4
在线时间
1173 小时
最后登录
2017-8-17
发表于 2017-8-3 17:21:39 | 显示全部楼层
擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦擦

回复 支持 反对

使用道具 举报

排名
36823
昨日变化
45

0

主题

5

帖子

10

积分

Rank: 1

UID
231046
好友
0
蛮牛币
32
威望
0
注册时间
2017-7-12
在线时间
1 小时
最后登录
2017-8-5
发表于 2017-8-5 14:57:11 | 显示全部楼层
谢谢分享,666

回复

使用道具 举报

4四处流浪
378/500
排名
12900
昨日变化
275

1

主题

282

帖子

378

积分

Rank: 4

UID
234498
好友
0
蛮牛币
1435
威望
0
注册时间
2017-7-27
在线时间
51 小时
最后登录
2017-8-17
发表于 2017-8-7 08:04:04 来自Mobile--- | 显示全部楼层
感谢分享,66663

回复

使用道具 举报

排名
26821
昨日变化
27

0

主题

23

帖子

61

积分

Rank: 2Rank: 2

UID
119006
好友
0
蛮牛币
1
威望
0
注册时间
2015-8-20
在线时间
30 小时
最后登录
2017-8-14
发表于 3 天前 | 显示全部楼层
66666666666666666

回复 支持 反对

使用道具 举报

7日久生情
1703/5000
排名
1374
昨日变化
2

5

主题

573

帖子

1703

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
143831
好友
2
蛮牛币
3079
威望
0
注册时间
2016-3-29
在线时间
435 小时
最后登录
2017-8-17

蛮牛译员活力之星七夕浪漫情人

发表于 前天 22:14 | 显示全部楼层
66666666666666666666666

回复 支持 反对

使用道具 举报

排名
49357
昨日变化
192

0

主题

3

帖子

7

积分

Rank: 1

UID
236768
好友
0
蛮牛币
25
威望
0
注册时间
2017-8-9
在线时间
2 小时
最后登录
2017-8-17
发表于 28 分钟前 | 显示全部楼层
已阅,很nice

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表