Unity - LayerMask简析
本文简述了LayerMask的定义,后通过项目实战充分解析 LayerMask中的GetMask、LayerToName、NameToLayer 等函数的使用方法及其注意事项。
项目地址:3D坦克大战 - SouthBegonia
LayerMask 定义
用来表示32个Layer层级的位掩码,类型为Int32,。前面8个是引擎使用的,后面24个供开发人员使用的。通过LayerMask我们可以实现诸多类似 层判定、层限制、层检测 的方法。的我们可以在Edit->Project Setting->Tags and Layers->Layers 中看到这32层(见下图)

LayerMask 方法
GetMask
函数原型:public static int GetMask(params string[] layerNames)
功能:传入一个图层名称列表,返回这个图层列表的等效图层蒙版。此处大家再回看上面的函数原型可能会产生疑问:何为等效图层蒙版,为何它的类型为int?它的用处是什么?
解析:我们先Debug看看上图中第1层和第5层看看:
//Way1:GetMask方法
Debug.Log(LayerMask.GetMask("Default"); -->1
Debug.Log(LayerMask.GetMask("Default", "UI")); -->33
一个非常奇怪的数据,但是我们转换成二进制呢?
1 --> 0001
33 --> 0010 0001
不难发现,这是Int32的位掩码,即LayerMask,第1、5位数为1表示开启了这两个层。因此可以说:等效图层蒙版 == 启用/关闭某几层的LayerMask位掩码, 1表示开启,0表示关闭。此外我们还可以使用位运算实现等效图层蒙版:
//Way2:位操作方法
LayerMask layer1 = (1 << 0);
LayerMask layer2 = (1 << 0) | (1 << 5);
Debug.Log(layer1.value); -->1
Debug.Log(layer2.value); -->33
//等效于:
LayerMask layer3 = LayerMask.GetMask("Default","UI");
Debug.Log(layer3.value); -->33
//其他位操作方法:
LayerMask layer4 = (0 << 5); //关闭索引为5的层
LayerMask layer5 = ~(1 << 5); //打开除了索引为5的层之外的层
那么怎么落实到项目中呢?在此提供一个项目示例(地址在文章首):我们在开发坦克大战游戏,有红蓝绿三方阵营,我们想让各自阵营的炮弹不伤害到友军,这时我们就需要用到LayerMask:
//设置LayerMask的类:
public class LayerManager : MonoBehaviour
{
public static int blueLayer = 10;
public static int greenLayer = 11;
public static int redLayer = 12;
//传入玩家所在Team的结构体变量,返回敌人所在的图层蒙版
static public LayerMask GetEnemyLayer(Team team)
{
LayerMask mask = 0;
switch (team)
{
case Team.Blue:
mask = (1 << redLayer) | (1 << greenLayer); //开启redLayer层和greenLayer层
break;
case Team.Green:
mask = (1 << redLayer) | (1 << blueLayer);
break;
case Team.Red:
mask = (1 << blueLayer) | (1 << greenLayer);
break;
}
return mask;
}
}
//炮弹脚本的碰撞检测片段:
public void OnCollisionEnter(Collision collision)
{
//射线检测球形范围内enemyLayers层敌人的collider
Collider[] cols = Physics.OverlapSphere(transform.position, explotionRadius, enemyLayers);
//炮弹仅对敌人阵营(敌人所在图层)造成伤害
}
//机理概述:
//1. 通过传入坦克自身所在阵营信息如蓝方阵营到GetEnemyLayer(),得到敌人红绿阵营的 layermask 并设置为 enemyLayers
//2. 我们在发射出的炮弹的脚本中就通过该 enemyLayers 限制了仅能检测到敌方layer层的碰撞体
//3. 实现炮弹对敌伤害而友军安全
LayerToName / NameToLayer
函数原型:public static string LayerToName(int layer)、public static int NameToLayer(string layerName)
功能:将索引值k转换为第k层的名称、将第k层的名称转换为k索引值
示例:
Debug.Log(LayerMask.NameToLayer("Blue")); -->10
Debug.Log(LayerMask.LayerToName(10)); -->Blue
//检测物体是否在某Layer
if (gameObject.layer == LayerMask.NameToLayer("Default"))
Debug.Log("Yes!");
总述
LayerMask是Unity中 操控Layer层的类,我们在使用时需要注意数据类型转换,其用法常体现在物理检测、射线检测等
关于射线检测可移步博主拙作:Unity射线检测 - SouthBegonia
参考
Unity - LayerMask简析的更多相关文章
- Unity5中新的Shader体系简析
一.Unity5中新的Shader体系简析 Unity5和之前的书写模式有了一定的改变.Unity5时代的Shader Reference官方文档也进一步地变得丰满. 主要需要了解到的是,在原来的Un ...
- Entitas实现简析
Entitas实现简析 这里主要讲Entitas的执行原理,不讲Entitas的代码生成方面. ECS简介 ECS(实体-组件-系统)是一种常用于游戏开发的架构模式. 实体: 实体只是一个 ...
- 简析.NET Core 以及与 .NET Framework的关系
简析.NET Core 以及与 .NET Framework的关系 一 .NET 的 Framework 们 二 .NET Core的到来 1. Runtime 2. Unified BCL 3. W ...
- 简析 .NET Core 构成体系
简析 .NET Core 构成体系 Roslyn 编译器 RyuJIT 编译器 CoreCLR & CoreRT CoreFX(.NET Core Libraries) .NET Core 代 ...
- RecycleView + CardView 控件简析
今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleVi ...
- Java Android 注解(Annotation) 及几个常用开源项目注解原理简析
不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...
- PHP的错误报错级别设置原理简析
原理简析 摘录php.ini文件的默认配置(php5.4): ; Common Values: ; E_ALL (Show all errors, warnings and notices inclu ...
- Android 启动过程简析
首先我们先来看android构架图: android系统是构建在linux系统上面的. 所以android设备启动经历3个过程. Boot Loader,Linux Kernel & Andr ...
- Android RecycleView + CardView 控件简析
今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleVi ...
随机推荐
- DDL/DML/DCL区别
DDL DDL的概述 DDL(Data Definition Language 数据定义语言)用于操作对象和对象的属性,这种对象包括数据库本身,以及数据库对象,像:表.视图等等,DDL对这些对象和属性 ...
- python 启动pydoc查看文档
启动pydoc查看文档 python3 -m pydoc -p 访问http://localhost:6789 或者查看官方文档:https://seleniumhq.github.io/seleni ...
- WAMP配置允许外网访问、绑定域名
如果wamp默认端口已经被占用,需要修改,则打开apache目录下的,conf文件下的httpd.conf文件 如图,把框中的默认80端口修改为自己需要的端口,然后重启WAMP即可. 想要实现外网访问 ...
- putty WinScp 免密登录远程 Linux
该方法的原理是预先生成一对公钥和私钥,私钥以文件的形式保存在本地,公钥保存在远程机器上.这样每次登录只需指定私钥文件,远程机器通过比对公钥和私钥来验证登录的合法性. Putty 免密登录 第一步 生成 ...
- 面试官问线程安全的List,看完再也不怕了!
最近在Java技术栈知识星球里面有球友问到了线程安全的 List: 扫码查看答案或加入知识星球 栈长在之前的文章<出场率比较高的一道多线程安全面试题>里面讲过 ArrayList 的不安全 ...
- spring(一)IOC & AOP
参考文档: spring详解:http://www.cnblogs.com/ysocean/p/7466191.html(可以说非常详细了) aop源码详解:https://www.cnblogs.c ...
- 数码视讯Q7的刷机
Q7的硬件配置 CPU: S905LRAM: MIRA P3P4GF4DMF DDR3 512MB * 2 = 1GBROM: 镁光29F64G08CBABB * 1 = 8GBWIFI: RTL81 ...
- Myeclipse安装Maven插件
Myeclipse安装Maven插件 一.下载Maven 官网下载maven插件 http://maven.apache.org/download.cgi 下载apache-maven-3.6.3- ...
- 如何单独编译Linux内核源码中的驱动为可加载模块?
答: 分为两步: 1. 配置某个驱动为模块(如: CONFIG_RTC_XXX=m) 2. 指定路径并编译, 如编译drivers/rtc中的驱动 make SUBDIRS=drivers/rtc m ...
- vue---引入外部样式
在用 vue-cli 进行项目开发的时候,经常会遇到要引入外部的样式,那该怎么做的呢? 示例:使用 import 引入 scss import variables from '@/assets/sty ...