本文简述了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简析的更多相关文章

  1. Unity5中新的Shader体系简析

    一.Unity5中新的Shader体系简析 Unity5和之前的书写模式有了一定的改变.Unity5时代的Shader Reference官方文档也进一步地变得丰满. 主要需要了解到的是,在原来的Un ...

  2. Entitas实现简析

    Entitas实现简析   这里主要讲Entitas的执行原理,不讲Entitas的代码生成方面. ECS简介   ECS(实体-组件-系统)是一种常用于游戏开发的架构模式.   实体: 实体只是一个 ...

  3. 简析.NET Core 以及与 .NET Framework的关系

    简析.NET Core 以及与 .NET Framework的关系 一 .NET 的 Framework 们 二 .NET Core的到来 1. Runtime 2. Unified BCL 3. W ...

  4. 简析 .NET Core 构成体系

    简析 .NET Core 构成体系 Roslyn 编译器 RyuJIT 编译器 CoreCLR & CoreRT CoreFX(.NET Core Libraries) .NET Core 代 ...

  5. RecycleView + CardView 控件简析

    今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleVi ...

  6. Java Android 注解(Annotation) 及几个常用开源项目注解原理简析

    不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...

  7. PHP的错误报错级别设置原理简析

    原理简析 摘录php.ini文件的默认配置(php5.4): ; Common Values: ; E_ALL (Show all errors, warnings and notices inclu ...

  8. Android 启动过程简析

    首先我们先来看android构架图: android系统是构建在linux系统上面的. 所以android设备启动经历3个过程. Boot Loader,Linux Kernel & Andr ...

  9. Android RecycleView + CardView 控件简析

    今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleVi ...

随机推荐

  1. 保存tensor至本地文件

    path_temp = '../m39_data/temp3' #文件目录 file_name = os.path.join(path_temp, "setQ.txt") Q = ...

  2. GSEA 基因集富集分析

    http://software.broadinstitute.org/gsea/index.jsp GSEA(Gene Set Enrichment Analysis)是一种生物信息学的计算方法,用于 ...

  3. OpenFOAM——孔板流量计

    本算例来自<ANSYS FLUENT技术基础与工程应用:流动传热与环境污染控制领域> 一个入口,入口速度为0.0176839m/s,一个出口边界,其余为壁面边界 流体的物性参数: 密度:1 ...

  4. pyqt(day1)

    参考代码地址:https://github.com/cxinping/Pyqt5 pyqt在线帮助文档:https://www.riverbankcomputing.com/static/Docs/P ...

  5. MongoDB笔记: 分片集群

    MongoDB分片集群由三个模块组成 shard: 分片(或者分区)模块, 每个分片分别存储一部分数据, 从MongoDB 3.6开始, 分片必须是replica set(副本集) mongos: m ...

  6. 全新思维导图 XMind ZEN v10.0.0 中文破解版

    http://www.carrotchou.blog/20331.html 官网 https://www.xmind.cn/ 注意事项 破解版本已经去除了全部的官方试用版的限制,让大家可以像正版用户一 ...

  7. Executors创建四种线程池

    newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixedThreadPool 创建一个定长线程池,可控制线程 ...

  8. Java8 lambda表达式10个示例<转>

    例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runna ...

  9. xpath库学习

    xpath解析是我们在爬虫中最常用也是最通用的一种数据解析方式. 环境安装 pip install lxml 解析原理 使用通用爬虫爬取网页数据 实例化etree对象,且将页面数据加载到该对象中 使用 ...

  10. ubuntu 16 typora 安装 ,14系统的不管用。。

    # sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA300B7755AFCFAE linuxidc@linuxidc:~ ...