12 第1页 | 共2 页下一页
返回列表 发新帖
查看: 21414|回复: 13
打印 上一主题 下一主题

[教程] Unity3d中的碰撞检测(二)

[复制链接]

21

主题

7

听众

651

积分

初级设计师

Rank: 3Rank: 3

纳金币
0
精华
3

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2012-11-2 19:04:59 |只看该作者 |倒序浏览
          上一篇我们了解了Unity里面的碰撞检测的两种方式,都能够很好的解决特定情形下的相关问题。这一话我紧接着介绍LayerMask(层蒙版)的应用,主要用在镜头穿墙上面。但是前提是读者对Unity里面的射线的应用有一个清楚的认识。

        Ray!射线,这并不是Unity里面独有的工具,其应用非常之广,而且此工具及其易用。利用它,你能极其快速的解决一些棘手的问题,比方说:鼠标点击屏幕,主角朝向鼠标点击的世界方向运动。此时,如果不利用射线的话,实现方式不会简单,特别是主角的运动方向的确定。好了,不费话了,看API:
    Ray : a ray is infinite line starting at origin and going in some direction.
我来用我自己理解的方式翻译一下:
一个射线是无限长的。它靠一个原点( origin ,Vector3类型)和一个方向( direciton,Vector3类型)决定。这是当然的,只需这两点,就能在一个三维空间确定一条射线。我们来看一下它的构造方法:



官方给出的实例化一条射线的代码:



看了这个之后,我们实例化一条射线就没问题了吧,注意:上面代码中的:transform.forward指的是该脚本绑定的GameObject自身坐标系下的Z轴在世界坐标系下的单位方向向量。

我们来看一下它的两个变量:



这两个东西我们从名字上面就能看出是什么,单词不认识的可以开有道。但是作为一个文化人,这种基本的单词应该记下来,我说的对吧!
好了,该看看函数了:


这个函数的功能是取得该射线从原点到距离为distance的一个点的坐标。



这个函数用的不多,功能比较简单:打印一条射线的基本信息,读者可以试着打印一下,就像java里面直接用
System.out.println(Object) 打印一个对象得出一个哈希码一样。
接下来我们该看看一个非常重要的类了:Physics,这个类里面的方法很多( 说实话,我只用过一个 ),我们重点看下面一个:


由于这个函数有好几个重载方法,我们今天仅介绍下面这个重载方法:





我们可以清楚地看出:
这个方法里面的前两个和Ray里的构造函数一模一样,这两者之间好像有着某种联系。这是必然的,因为还有下面这个重载函数:




看到没,很坑吧。不过,这也是API的一个亮点,多样化。两个方法的底层实现是一样的。
下面我来着重介绍这几个参数的意义:
orign与direction就不用介绍了吧,一个是原点,一个是方向。第三个从字面上理解是距离,第四个是射线的碰撞信息类,里面包含很多我们可以得到的信息,第五个就是我们今天必须理解的一个很实用的工具:LayerMask( 层蒙版 )。
这个函数的功能按我的理解是这样的:以点origin为原点,direction为方向,在世界空间中发射射线,如果在distance距离内与其他在kDefaultRaycastLayers层级之中的GameObject发生碰撞,那么此函数就返回ture,并且记录碰撞信息。
那么什么是LayerMask呢?我们打开Unity,随便找一个GameObject,哪怕是空的GameObject,你都会发现这样一个显示图标:


看到没?有个Layer,我们试着单击一下这个下拉框:



不好意思,我截图的技术真的很烂,但是我们还是可以隐隐约约看到有好几个选项可供选择,如:Default,TransparentFX等,那么这到底有什么用呢?

原来,Unity再设计GameObject时,对GameObject的做了一种分层的处理。举个例子吧:我们选中任意一个摄像机:可以在Inspector面板中找到这样一项:


Culling Mask,又出现了一个Mask,这和LayerMask又有什么联系呢?算了,我直接说吧:默认情况下摄像机可以渲染任何层级中的GameObject,但当我们在CullingMask中有层没选,那么摄像机在渲染时,就不会渲染这一层的物体,Game视图也就不会出现处在这一层的GameObject。此时Culling Mask选项会出现:Mixed...这种结果。当我们选择Nothing,那么Game视图里面必定不会出现任何GameObject。这个层级我们可以在Unity编辑器的菜单下:Edit->roject setting->Tags下找到:



我们可以看到我们刚才看到的那几个层级名。那么我们现在该了解一下LayerMask这个类了。
    由于文档上讲的我自己都不大明白,后来差了些资料,终于算是知道了这个东西的用法了。LayerMask在程序中我们可以用一个int型的变量对其进行赋值,但是这种赋值可不是随便胡乱赋的。我们看上图,一共有32层,有7个内建层,但是只有4个层是有名字的,分别为:Default  , TransparentFX , Ignore Raycast,Water。而且这四个层并不是连续的( 为什么要这样设计那是开发Unity技术部门决定的,不必太在意这个)。然后,我们可以从第9层:User Layer 8这一层开始,我们可以自定一个层的名字。好了,我们来看LayerMask这个类里面的用法吧:


这是我在文档上截的图,LayerMask有一个变量value,就是这个层级的层级值。让我们来看看下面的三个方法吧,我把这三个方法翻译如下:
1.LayerMask.operatorLayerMask( int intVal ) :LayerMask

给定一个int型的层级号,我们可以得到一个LayerMask对象。

2.LayerMask.LayerToName( int layer ) : string
给定一个int型的层级号,我们将其层级名返回。

3.LayerMask.NameToLayer( string layerName ) : int
给定一个层级名,我们将此层级的层级号返回。

那么我们来打印几个层级的层级好吧,代码比较简单,如下:

using UnityEngine;
using System.Collections;



public class TestLayerMask : MonoBehaviour {

// Use this for initialization
void Start () {

        for (int i = 0; i < 32;i++ )
        {
            Debug.Log(LayerMask.LayerToName(i));
        }
    }

}
代码的功能很简单,就是打印第0层到第31层的层级名,部分结果如下:


可以清楚地发现,当i=0时,我们的层级名是:Default。然后后面有的没有打印出层级名的,原因我就不多说了,你也明白。这样我们就可以得出一个结论:如果一个层属于第i(i介于0到31之间,可以等于)层,那么这个层级的层级序号就为i。对于那些只读的层,我们无法修改其名字。比如内建层。
那么能不能将一个层级序号为5的层级转化为一个LayerMask?答案是不行的,因为这个层在面板里面不能访问。你可以试一下。
        估计大伙现在应该对LayerMask这个类有一定的理解了吧。那好,接下来我会在第三篇文章中重点讲解摄像头的一个穿墙问题,就用到了这个LayerMask,敬请期待。


分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

may    

8830

主题

81

听众

7万

积分

首席设计师

Rank: 8Rank: 8

纳金币
52336
精华
343

最佳新人 热心会员 灌水之王 活跃会员 突出贡献 荣誉管理 论坛元老

沙发
发表于 2012-11-2 19:06:56 |只看该作者
SF!呵呵
回复

使用道具 举报

955

主题

164

听众

7万

积分

版主

Rank: 7Rank: 7Rank: 7

纳金币
59338
精华
28

活跃会员 荣誉管理 突出贡献 优秀版主 论坛元老

板凳
发表于 2012-11-2 20:13:01 |只看该作者
感谢分享精彩的教程!
回复

使用道具 举报

2722

主题

42

听众

3万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
38268
精华
111

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

地板
发表于 2012-11-6 14:27:48 |只看该作者
很不错的教程分享啊。谢谢
回复

使用道具 举报

.    

3797

主题

11

听众

5万

积分

首席设计师

Rank: 8Rank: 8

纳金币
32328
精华
41

活跃会员 优秀版主 荣誉管理 论坛元老

5#
发表于 2012-11-8 21:15:30 |只看该作者
这是一个好帖子,大家快来围观!!
回复

使用道具 举报

2722

主题

42

听众

3万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
38268
精华
111

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

6#
发表于 2012-11-11 00:45:13 |只看该作者
顶起,楼主的教程很不错啊,学习学习!
回复

使用道具 举报

21

主题

7

听众

651

积分

初级设计师

Rank: 3Rank: 3

纳金币
0
精华
3

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

7#
发表于 2012-11-11 07:37:31 |只看该作者
这是我自己的一些心得,希望圈友多支持一下,多来踩踩。
回复

使用道具 举报

2317

主题

54

听众

2万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
20645
精华
62

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

8#
发表于 2012-11-11 12:22:15 |只看该作者
希望能介绍一下light probe这个东西的用法,貌似很多论坛都没看到相关的教程。
回复

使用道具 举报

19

主题

3

听众

1357

积分

助理设计师

Rank: 4

纳金币
636
精华
0

活跃会员

9#
发表于 2013-5-29 11:45:31 |只看该作者
谢谢了 很好的教程
回复

使用道具 举报

0

主题

1

听众

467

积分

设计实习生

Rank: 2

纳金币
35
精华
0

最佳新人

10#
发表于 2013-5-30 15:55:19 |只看该作者
thaks for shares
回复

使用道具 举报

12 第1页 | 共2 页下一页
返回列表 发新帖
您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-15 23:44 , Processed in 0.226107 second(s), 31 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部