【Unity】Tag、Layer、LayerMask

文章目录

  • 层(Layer)
    • 什么是Layer
    • Layer的应用场景
    • Layer层的配置(Tags & Layers)
    • Layer的数据结构
    • LayerMask
    • Layer的选中和忽略
    • Layer的管理(架构思路)
    • 层碰撞矩阵设置(Layer Collision Matrix)
    • 层排序(Sorting Layers)
      • 设置2D物体的Sorting Layer
      • 设置2D物体的Order In Layer
  • 标签(Tag)
    • Tag标签的配置
    • 给物体设置标签
    • Tag的基本用法
      • 获取场景中的物体
      • 判断物体是否具有某个Tag
    • Tag标签的应用场景


层(Layer)

什么是Layer

在Unity中,Layer的核心作用其实就是给游戏对象分类,这样我们就可以针对这些类别进行统一处理。比如我正在做一个Moba游戏,需要一个小地图,我打算用一个相机从地图上方俯视,这时候我需要在地图中显示一些标记(比如玩家的标记,怪物的标记)在地图上,这些标记是跟着玩家移动的,但是我的主相机中又不想看到这些标记,这时候就可以把这些标记指定为一个特殊的层,比如 “MapSignal” ,然后我们将主相机设置为不看 “MapSignal” 层,我们的功能就实现了。反之,我们可以在地图相机上,将玩家的Layer去掉,只保留 “MapSignal” 层,这样地图相机就不会显示玩家模型了。

Layer的应用场景

刚才举的例子只是 Layer 的一种用法,实际上 Layer 还有很多种作用,具体如下:

  1. 在 Scene 视图中隐藏某些 Layer ,可以在Scene视图工具栏中选择Layers,通过设置哪些Layer将出现在Scene视图中,以及哪些Laver不会出现;
  2. 排除不被灯光照亮的 Layer ,在创建自定义的用户界面、阴影系统或者使用复杂的光照系统时,可以选择灯光对象,然后在对应的Inspector视图中点击Culling Mask属性,取消选择你想忽略的那些Layer;
  3. 用于物理交互。在 Edit => ProiectSetings => Physics 菜单中,可以找到Layer Colision Matrix属性,用它来设置哪些游戏对象之间可以进行物理交互
  4. 用于射线检测的 Layer 。在某些情况下,可以使用 Layer 来忽略一些 Collider或Collision,比如在做射线检测时;
  5. 通过名称获取 Layer ,并 “开启 / 关闭” Layer ,可以通过 LayerMask.NameToLayer 方法获取特定的 Layer ,例如:int layer = LaverMask NameToLayer("Enemy");,然后可以使用1左移位运算符开启并获取Enemy Layer层,或者使用0左移位运算符关闭并获取Enemy Layer层。

Layer层的配置(Tags & Layers)

Unity中有一个用于设置标签(Tag)和层(Layer)的面板叫做 “Tags & Layers” ,打开方式很简单,只要选定场景中的任意对象,然后在Inspector面板中点击 Layer => Add Layer 即可。也可以在主菜单中点击 Edit => Project Settings,然后选择 Tags and Layers 标签页。
在这里插入图片描述
在这里插入图片描述

Layer的数据结构

Layer 数据其实是一个 int 值,每个 Layer 都是一个 int 值,且该值是 2 的 N 次方,看到这里相信有经验的人都知道是二进制的计算方法,由于 int32 是一个 32 位的二进制数,所以 Unity 的层也就设置了 32 个(0 ~ 31),所以每个层对应的数值就是 2 的 0 ~ N 次方,比如第 0 个 Layer 对应的值是 1,第 8 个 Layer 对应的值是 256 ,第十个 Layer 则是 1024。那么假如我给定一个数是 257 ,就代表了我同时拥有第 0 层( 2的0次方 = 1 )和第 8 层( 2的8次方 = 256 ),如下图,Layer0(Default)对应的int值就是2的0次方 = 1,而Layer7(Player)对应的就是2的7次方 = 128。当我们想要同时指定多个层时,就可以使用一个int值来表达。
在这里插入图片描述

LayerMask

LayerMask可以用来指定一个范围,以帮助检测物体是否在范围内,或设置射线是否会打到某个范围的层上。以射线为例:

// 指定第八层和第九层
int layers = (1 << 8) | (1 << 9);
// 入射射线
var ray = new Ray(startPoint, inDircection);
// 射线只会检测第八层和第九层的物体
var hits = new List<RaycastHit>(Physics.RaycastAll(ray, distance, layers));

在上面的案例中,射线只会检测第八层和第九层的物体,这样不但提高了运行效率,还使代码逻辑更为简洁,不需要手动判断物体类型。

Layer的选中和忽略

在代码中使用 | 可以使多个层联系在一起,使用 ~ 则会将指定的层排除掉,如下图:
在这里插入图片描述

Layer的管理(架构思路)

由于不确定在什么样的时候有可能会修改Layer的名称,所以不建议在代码中直接写入大量的Layer名称,所以通常要搞一个层的维护类,将层的名字做成常量,并提供更便捷的访问方式,代码如下:

using UnityEngine;namespace Battle.Logic.LayerMasks
{/// <summary>///     层管理器///     所有层Layer相关的操作都应该在此类中完成///     <para>///         <Author>开发者 : Genesis (*╹▽╹*) </Author>///     </para>/// </summary>public static class LayerMaskManager{/// <summary>///     地面层/// </summary>private const string LayerGround = "Ground";/// <summary>///     可触发的草///     玩家进入草丛后可以隐身/// </summary>private const string LayerTriggerGrass = "TriggerGrass";/// <summary>///     可触发的水///     玩家进入水后可能被减速甚至被淹死/// </summary>private const string LayerTriggerWater = "TriggerWater";/// <summary>///     可触发层///     通常是有触发器的碰撞体才会在这一层/// </summary>private const string LayerCanTrigger = "CanTrigger";/// <summary>///     可碰撞层///     通常是可以影响玩家位置的碰撞体才会在这一层/// </summary>private const string LayerCanCollide = "CanCollide";/// <summary>///     逻辑玩家层/// </summary>private const string LayerLogicPlayer = "LogicPlayer";/// <summary>///     显示玩家层/// </summary>private const string LayerDisplayPlayer = "DisplayPlayer";/// <summary>///     玩家是否接触地面的层遮罩/// </summary>public static LayerMask PlayerOnGroundLayerMask = LayerMask.GetMask(layerNames: new[] { LayerGround, LayerCanCollide });/// <summary>///     玩家投棉球瞄准线的Layer遮罩/// </summary>public static LayerMask PlayerAimLayerMask = LayerMask.GetMask(layerNames: new[] { LayerGround, LayerCanCollide });/// <summary>///     玩家投棉球子弹的Layer遮罩/// </summary>public static LayerMask CottonBulletLayerMask = LayerMask.GetMask(layerNames: new[] { LayerGround, LayerCanCollide });/// <summary>///     摆放炮台环节显示的Layer遮罩/// </summary>public static LayerMask DefensePutLayerMask =LayerMask.GetMask(layerNames: new[] { LayerGround, LayerTriggerGrass, LayerTriggerWater, LayerCanCollide });/// <summary>/// 判断obj是否在layerMask中/// </summary>/// <param name="obj">需要验证的物体</param>/// <param name="layerMask">指定的层</param>/// <returns>物体是否在指定的层中</returns>public static bool IsInLayerMask(GameObject obj, LayerMask layerMask){// 根据Layer数值进行移位获得用于运算的Mask值var objLayerMask = 1 << obj.layer;return (layerMask.value & objLayerMask) > 0;}/// <summary>/// 判断objMask是否在layerMask中/// </summary>/// <param name="objMask">需要验证的物体的层</param>/// <param name="layerMask">指定的层</param>/// <returns>该物体的层是否在指定的层中</returns>public static bool IsInLayerMask(LayerMask objMask, LayerMask layerMask){// 根据Layer数值进行移位获得用于运算的Mask值var objLayerMask = 1 << objMask;return (layerMask.value & objLayerMask) > 0;}}
}

在上面的代码中,我将项目中层的名称定义为常量,后续使用层的名称时只允许使用常量,不允许直接使用字符串形式的LayerName,这样一旦层的名称有改动只需要改动此常量即可。
然后又提供了一些常用的已经绑定好的LayerMask(例如:PlayerAimLayerMask),便于在代码中直接使用,使用代码如下:

// 入射射线
var ray = new Ray(startPoint, inDircection);
// 获取射线经过的点(这里对层进行了过滤)
var hits = new List<RaycastHit>(Physics.RaycastAll(ray, distance, LayerMaskManager.PlayerAimLayerMask));

层碰撞矩阵设置(Layer Collision Matrix)

Unity支持通过设置决定层与层之间的碰撞关系,如下图:
在这里插入图片描述
物理引擎在检测碰撞时会通过Layer Collision Matrix的设置内容来决定要针对哪些层做碰撞监测,勾选的层之间碰撞有监测,没有勾选的层之间完全不会产生任何碰撞。

层排序(Sorting Layers)

Sorting Layers的主要作用是用于改变2D物体的渲染顺序,在 Hierarchy 中创建的 Canvas,Unity 默认自上而下渲染,位置越靠后的 Canvas 将渲染在靠前位置的 Canvas 之上,但有时我们需要让位置后靠后的Canvas先进行渲染或者让位置靠前的Canvas后渲染,此时就要用到Sorting Layer。
在这里插入图片描述
如上图,越往上的层级渲染顺序越靠前,也就是说下面层级的物体会显示在更上面一些。

设置2D物体的Sorting Layer

在Sprite Renderer组件中有一个Additional Settings节点,下面可以设置与层相关的功能。想要物体显示的靠前,就设置相对较高的层级即可。
在这里插入图片描述

设置2D物体的Order In Layer

有时候在同一Sorting Layer下也要区分物体的渲染顺序,这时候就需要用到Order In Layer设置,跟Sorting Layer差不多,数值越大,渲染越靠前。

标签(Tag)

由于Layer的数据结构相对简单,类似简单的树状结构,在某些复杂条件下可能无法满足开发需求。所以,Unity在层之外还做了一个Tag(标签)功能,每个物体都可以设置相应的Layer和Tag,通过Tag就将简单的树形结构改成了网状结构,例如:同一个层的物体可以又有标签A又有标签B,这样做的好处是可以实现跨层对某类物体进行判定筛选。

标签有助于识别游戏对象以便于编写脚本。通过使用标签,不需要使用拖放方式手动将游戏对象添加到脚本的公开属性,因此可以节省在多个游戏对象中使用相同脚本代码的时间。

Tag标签的配置

Tag标签的配置和Layer在同一个功能页中,面板图示如下:
在这里插入图片描述
最上面的Tags就是用于设置标签的。

给物体设置标签

选中物体后,Inspector面板左上角会有一个Tag下拉菜单,可以用来设置物体的Tag。
在这里插入图片描述

Tag的基本用法

获取场景中的物体

Unity支持通过标签获取场景中的物体,代码如下:

// 获取场景中的标签为MyTag01的所有游戏对象
GameObject.FindGameObjectsWithTag("MyTag01")
// 获取具有MyTag01标签的第一个GameObject
GameObject.FindWithTag("MyTag01");

我们可以通过这种方式获取场景中的某一类别的物体,且不受层级Layer影响。

判断物体是否具有某个Tag

判断物体是否具有某个Tag可以使用**gameObject.CompareTag(string)**函数,代码如下:

void Update()
{// 假设你想检查这个GameObject是否有Tag为"Player"if (gameObject.CompareTag("Player")){// 如果是玩家,执行相关逻辑Debug.Log("This is the player.");}
}

Tag标签的应用场景

标签 (Tag) 是可分配给一个或多个游戏对象的参考词。例如,可为玩家控制的角色定义“Player”标签,并为非玩家控制的角色定义“Enemy”标签。还可以使用“Collectable”标签定义玩家可在场景中收集的物品。

标签对碰撞体控制脚本中的触发器很有用;例如,需要通过标签确定玩家是否与敌人、道具或可收集物进行交互。


更多内容请查看总目录【Unity】Unity学习笔记目录整理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/747161.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot(拦截器+文件上传)

文章目录 1.拦截器1.基本介绍2.应用实例1.去掉Thymeleaf案例中使用session进行权限验证的部分2.编写自定义拦截器 LoginInterceptor.java 实现HandlerInterceptor接口的三个方法3.注册拦截器1.第一种方式 配置类直接实现WebMvcConfigurer接口&#xff0c;重写addInterceptors方…

C++语言学习(一)—— 认识C++语言

目录 一、C语言 二、C与C语言的区别 2.1 预处理器 2.2 标准库 2.3 类型 2.4 函数重载 2.5 内存管理 2.6 输入输出函数 2.7 关键字 三、C的基本结构 一、C语言 C语言是一种高级编程语言&#xff0c;由Bjarne Stroustrup在20世纪80年代初设计和开发。它是C语言的扩展&a…

综合小区管理系统|基于Springboot的综合小区管理系统设计与实现(源码+数据库+文档)

综合小区管理系统目录 目录 基于Springboot的综合小区管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、出入管理 2、报修管理 3、车位管理 4、公告管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#…

git 将某些代码一个分支转移到另一个分支

https://blog.csdn.net/huyongfu2004/article/details/122239102 假设A分支已经有修改的代码 提交过了 但是没有合并到master&#xff1b; 想要吧A分支这次的修改单独提交 已经commit 查看提交的commit号 git log切到新的分支&#xff0c;后将该commit id pick到正确分支 g…

day06、07-MySQL

文章目录 一、MySQL概述1.1 安装1.2 数据模型1.3 SQL简介1.3.1 SQL通用语法1.3.2 分类 二. 数据库设计-DDL2.1 项目开发流程2.2 数据库操作2.2.1 查询数据库2.2.2 创建数据库2.2.3 使用数据库2.2.4 删除数据库 2.3 图形化工具2.3.1 介绍2.3.2 安装2.3.3 使用2.2.3.1 连接数据库…

【English Learning】Day13

2024/03/14 和小录打卡的第13天 目录 Words & phrases Words & phrases incrredibly incredibly busy 超级忙merely not merely 不仅仅tragedy a terible tregedy 可怕的悲剧a personal tragedy 个人遭遇strive strive to be best 努力做最好的strive for peace 为和平…

【项目管理】进度管理

一、前言 小型项目中&#xff0c;定义活动、排列活动顺序、估算活动持续时间及制定进度模型形成进度计划等过程的联系非常密切&#xff0c;可以视为一个过程&#xff0c;可以由一个人在较短时间内完成。项目管理团队编制进度计划的一般步骤为&#xff1a;首先选择进度计划方法…

Qt+FFmpeg+opengl从零制作视频播放器-7.OpenGL播放视频

在上一节Qt+FFmpeg+opengl从零制作视频播放器-6.视频解码中,我们学到了如何将视频数据解码成YUV原始数据,并且保存到本地,最后使用工具来播放YUV文件。 本节使用QOpenGLWidget来渲染解码后的YUV视频数据。 首先简单介绍QOpenGLWidget的使用。 QOpenGLWidget类是用于渲染O…

HTML—标签的分类,span和div标签,不同的标签之间类型转换

标签的分类&#xff1a; ①块级标签&#xff1a;无论内容多少&#xff0c;会充满整个行。大小可自定义 例&#xff1a;p&#xff0c;h1&#xff0c;ul&#xff0c;ol&#xff0c;hr 等 ②行级标签&#xff1a;自身的大小就是标签的大小&#xff0c;不会占一整行。大小不可调 例…

密码保护小贴士:如何应对常见的网络钓鱼攻击?

网络钓鱼攻击是一种常见的网络欺诈手段&#xff0c;针对个人隐私和财产安全构成威胁。以下是一些密码保护的小贴士&#xff0c;帮助您应对常见的网络钓鱼攻击&#xff1a; 1.谨慎点击链接&#xff1a;收到来历不明的邮件、短信或社交媒体消息时&#xff0c;不要轻易点击其中的…

Python 基础语法:基本数据类型(字典)

为什么这个基本的数据类型被称作字典呢&#xff1f;这个是因为字典这种基本数据类型的一些行为和我们日常的查字典过程非常相似。 通过汉语字典查找汉字&#xff0c;首先需要确定这个汉字的首字母&#xff0c;然后再通过这个首字母找到我们所想要的汉字。这个过程其实就代表了…

easyexcel导出excel文件到s3服务器

导出excel文件是开发中常见的需求 常见的做法一般是直接通过请求接口响应对象HttpServletResponse把文件输出 我们可以使用原生的poi工具类操作.也可以使用easypoi.easyexcel等基于poi二次封装的工具处理 下面是代码 /*** 导出列表** param request* param response*/Overri…

腾讯,百度后端实习一面面经base上海

腾讯面经 拷打后端项目 mysql查询去重怎么建表的项目中一些接口的实现设计场景&#xff1a;抖音有个搜索功能&#xff0c;要搜索并展示用户和视频的信息&#xff0c;你要怎么实现用户的鉴权是怎么设计的设置mysql连接池的参数的依据gorm怎么防止sql注入get和post的区别&#…

SPA富应用开发

1、开发环境的安装&#xff1a; 笔者在安装过程中&#xff0c;出现了版本问题&#xff0c;所以&#xff0c;在这里做出提醒&#xff0c;要是安装不成功&#xff0c;爆出版本问题&#xff0c;执行下面的命令&#xff0c;命令的来源是这里&#xff1a;Install Docker Engine on …

YoloV8改进策略:下采样改进|HWD改进下采样

摘要 本文使用HWD改进下采样&#xff0c;在YoloV8的测试中实现涨点。 论文解读 在卷积神经网络&#xff08;CNNs&#xff09;中&#xff0c;极大池化或跨行卷积等下采样操作被广泛用于聚合局部特征、扩大感受野和最小化计算开销。然而&#xff0c;对于语义分割任务&#xff…

2024年,如何长久做好一家抖音小店?明白这几点就可以了!

大家好&#xff0c;我是电商糖果 有人曾经问过糖果&#xff0c;自己做抖音小店想要长期去玩&#xff0c;可能要做个三四年&#xff0c;甚至更久。 糖果做电商7年了&#xff0c;从2020年开始做抖音小店&#xff0c;现在已经四年了。 所以你如果问我是怎么可以将这个项目做那么…

谷粒商城——分布式基础(全栈开发篇第一部分)

文章目录 一、服务治理网路数据支撑日志处理ELK应用监控集成工具开发工具 二、环境创建1、虚拟机创建2、虚拟机安装docker等1. 安装docker1. 配置阿里docker3.docker安装mysql错误 4、docker安装redis 3、软件1.Maven 阿里云镜像1.8jdk2、idea lombokmybatisX &#xff0c;3、 …

熔断降级的方案实现

熔断降级的方案实现 Spring Cloud Netflix Hystrix 提供线程隔离、服务降级、请求缓存、请求合并等功能可与Spring Cloud其他组件无缝集成官方已宣布停止维护&#xff0c;推荐使用Resilience4j代替 Spring Cloud Resilience4j 轻量级服务熔断库 提供类似于Hystrix的功能 具有更…

C++手写链表、反转链表、删除链表节点、遍历、为链表增加迭代器

本篇博客介绍如何使用C实现链表&#xff0c;首先编写一个简单的链表&#xff0c;然后增加模板&#xff0c;再增加迭代器。 简单链表的实现 链表的结构如下&#xff1a; 首先需要定义链表的节点&#xff1a; struct ListNode {int data;ListNode* pNext;ListNode(int value …

【C++算法模板】图论-拓扑排序,超详细注释带例题

文章目录 0&#xff09;概述1&#xff09;Kahn算法1&#xff1a;数据结构2&#xff1a;建图3&#xff1a;Kanh算法 2&#xff09;DFS染色1&#xff1a;数据结构2&#xff1a;建图3&#xff1a;DFS 3&#xff09;算法对比【例题】洛谷 B3644 推荐视频链接&#xff1a;D01 拓扑排…