Unity中的Layer实现

一:前言 

在项目中有的时候,希望一些游戏对象只能被某些摄像机看到或者只会被某些灯光照亮,就需要用到Unity中Layer层级
Unity用int32来表示32个层:0000 0000 0000 0000 0000 0000 0000 0000,1表示开启,0表示关闭,实际的LayerMask值是通过二进制存储的


二:位运算符

位运算符是对二进制进行运算的运算符

——与运算符:只有两个位都是1,结果才是1
——或运算符:只要两个位有一个是1,结果就是1
——非运算符:如果位为0,结果是1,如果位为1,结果是0
——异或运算符:两个操作数的位中,相同则结果为0,不同则结果为1
——左移运算符<<:左移多少位表示乘以2的几次幂
——右移运算符>>:右移多少位表示除以2的几次幂

使用位运算符的几个小例子:
——判断一个数是否为偶数:if (0 == (a & 1))
——判断一个数是否为奇数:if (1 == (a & 1))
——不使用临时变量,交换两个数

a=1,b=2;
a=a^b;
b=a^b;
a=a^b;


因为,一个数和自己进行异或运算,得到的是0。一个数和0进行异或运算,得到的还是这个数。


三:常用方法

——LayerMask.GetMask
获取到的是一个int值,这个值称为等效图层蒙版,其实是二进制值对应的十进制值,例如LayerMask.GetMask("UI"),获取到的值是32,转换为二进制后为0010 0000,表示第五层


——LayerMask.LayerToName
传入层级的index,获取到层级名称


——LayerMask.NameToLayer
传入层级的名称,获取到层级的index


——设置Layer
LayerMask mask=1<<需要开启的Layers层
LayerMask mask=0<<需要关闭的Layers层

开启第5层
LayerMask mask=1<<5或LayerMask mask=1<<LayerMask.NameToLayer("UI")
关闭第五层
LayerMask mask=0<<5或LayerMask mask=0<<LayerMask.NameToLayer("UI")
开启第5层和第六层
LayerMask mask=1<<5|1<<6
给相机添加渲染层
Component<Camera>().cullingMask |= 1 << 5
给相机移除渲染层
Component<Camera>().cullingMask &= ~(1 << 5)
相机只保留UI层
camera.cullingMask &= ~(1 << LayerMask.NameToLayer("UI"));
开关UI层,如果是开的则关,如果是关的则开
camera.cullingMask ^= 1 << LayerMask.NameToLayer("UI");


四:自定义一个像LayerMask的枚举


其实Unity中提供了Flags特性可以实现,将Flags标签特性定义在枚举类型上即可
这里我们使用PropertyDrawer重绘面板,自定义一个EnumFlags特性

using System;
using UnityEditor;
using UnityEngine;

public sealed class EnumFlagsAttribute : PropertyAttribute
{
    public Type EnumType;
    public EnumFlagsAttribute(Type enumType)
    {
        EnumType = enumType;
    }
}

[CustomPropertyDrawer(typeof(EnumFlagsAttribute))]
public class EnumFlagsDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EnumFlagsAttribute target = attribute as EnumFlagsAttribute;
        EditorGUI.BeginProperty(position, label, property);
        if (property.propertyType == SerializedPropertyType.Enum)
        {
            var e = EditorGUI.EnumFlagsField(position, target.EnumType.Name, (Enum)Enum.ToObject(target.EnumType, property.intValue));
            property.intValue = Convert.ToInt32(e);
        }
        EditorGUI.EndProperty();
    }
}

定义一个枚举类型,枚举类型的值,添加

using UnityEngine;
using System;

public enum ELevel
{
    Level1 = 1 << 0,
    Level2 = 1 << 1,
    Level3 = 1 << 2,
    Level4 = 1 << 3,
}

public class Test : MonoBehaviour
{
    [EnumFlags(typeof(ELevel))]
    public ELevel level;

    public void Start()
    {
        //添加某个选项
        level |= ELevel.Level1;

        //移除某个选项
        level &= ~ELevel.Level1;

        //判断是否包含某个值
        if ((level & ELevel.Level1) != 0)
        {
            Debug.Log("被选中");
        }
        else
        {
            Debug.Log("没有被选中");
        }
        //判断是否包含某个值
        if ((level & ELevel.Level1) == ELevel.Level1)
        {
            Debug.Log("被选中");
        }
        else
        {
            Debug.Log("没有被选中");
        }
        //判断是否包含某个值
        bool contain = level.HasFlag(ELevel.Level1);
    }
}

它的内部是这样实现的,例如如上定义的枚举,初始化时选的是Level1(0001),当选择Level3时,0001|0011=0011,之后将0011和每一个枚举值进行&操作,如果结果等于被比较的枚举值本身,那么这个值就是被选中的


五:编辑器中的Layer

选择Unity菜单栏的Layers,出现一个下拉栏

这里标示出了显示在Scene视图物体的Layer
例如将Default层的小眼睛图标闭上,Scene视图中则不会显示Layer为Default的物体
例如将Default层的锁给锁上,在Scene视图中则不能对Layer为Default的物体进行任何操作

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容使用说明 YOLO高分设计资源源码,详情请查看资源内容使用说明 YOLO高分设计资源源码,详情请查看资源内容使用说明 YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello Bug.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值