Unity中的枚举和标志

译林军 宿学龙|2014-04-10 08:56|9007次浏览|Unity(377)0

枚举和标志

今天的主题是枚举,它是C#语言中的一个很有帮助的工具,可以增强代码的清晰度以及准确性。

枚举一系列值

C#中最经常使用枚举的地方就是用来定义一系列可能值的时候。例如在制作一个角色类游戏中,角色有多个不同的状态效果。可以用一些基本的方式来定义玩家可能的状态效果:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

using UnityEngine;

 

public class Player : MonoBehaviour

{

    public string status;

 

    void Update()

    {

        if (status == "Poison")

        {

            //Apply poison effect

        }

        else if (status == "Slow")

        {

            //Apply slow effect

        }

        else if (status == "Mute")

        {

            //Apply mute effect

        }

    }

}

此处我们用一个简单的if-else检测来查看应用的是哪个状态效果,哪个运行良好。但是如果你想应用一个状态效果,但是突然写成这样:


1

2

//Oops, I spelled "Poison" wrong!

status = "Pioson";

突然,就不会有什么状态效果了。我们会利用if-else栈检测来查看我们的变量是否被设置成一个非法值,但是如果使用枚举,则是一种更好的方式:

定义一个枚举

这次我们使用一个枚举来编写我们的状态效果:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

using UnityEngine;

 

public class Player : MonoBehaviour

{

    //This is the "set" of all possible status effects

    public enum StatusEffect

    {

        None,

        Poison,

        Slow,

        Mute

    }

 

    //Now we can make a variable using that set as its type!

    public StatusEffect status;

 

    void Update()

    {

        if (status == StatusEffect.Poison)

        {

            //Apply poison effect

        }

        else if (status == StatusEffect.Slow)

        {

            //Apply slow effect

        }

        else if (status == StatusEffect.Mute)

        {

            //Apply mute effect

        }

    }

}

这里我们定义了一个叫StatusEffect的枚举,通过给状态赋值,我们强制编译器只等于StatusEffect中的一个值,如果还像之前赋值:


1

2

//This type doesn‘t even exist, ERROR TIME!

status = StatusEffect.Pioson;

游戏就不可能运行,编辑器会抛出一个错误,告诉你正在使用一个非法的枚举值,并指出你需要修复的确切的代码行。

在上述代码中,我没有制定状态的默认值,通常来说,一个枚举都是指定集合中的第一个值作为默认值的,因此在此例中,我已经说过,StatusEffect变量的任意默认值都是StatusEffect.None。

如果你发现Unity中有专门为UI自定义的枚举,那就更好了,当我打开Player组件的查看器时,看看发生什么了。

一个干净整洁的下拉菜单用来选择定义的类型!

枚举位标志

StatusEffect枚举,如下:


1

2

3

4

5

6

7

8

[System.Flags]

public enum StatusEffect

{

    None    = 1,

    Poison    = 2,

    Slow    = 4,

    Mute    = 8

}

通过如此,我们告知编译器将此枚举看做是位标记,表示每个不同的枚举值代表一个不同的位。这意味着我们必须通过给它们用2的幂来赋值,以此告知每个枚举值。另一种就是通过获取两个值的幂,然后通过移位来实现:


1

2

3

4

5

6

7

8

[System.Flags]

public enum StatusEffect

{

    None   = 1 << 0, // 1

    Poison = 1 << 1, // 2

    Slow   = 1 << 2, // 4

    Mute   = 1 << 3  // 8

}

现在可以通过平常的位操作来控制这些枚举域了。如果你对位操作不熟悉,我会简单讲解下如何使用。

枚举标志和位操作符

现在我们的枚举值是通过System.Flags标记的,我们可以像之前一样,如下来做:


1

2

//Character is poisoned!

status = StatusEffect.Poison;

但如果玩家中毒或者行动缓慢怎么办?我们可以使用或|操作符来将多个状态值合并一起:


1

2

3

4

5

6

7

8

9

//Now we are poisoned *and* slowed!

status = StatusEffect.Poison | StatusEffect.Slow;

 

//We could also do this:

//First we are poisoned, like so

status = StatusEffect.Poison;

 

//Then we become *also* slowed later

status |= StatusEffect.Slow;

如果我们想移除一个状态效果,我们可以使用&操作符和取反~。


1

2

3

4

5

//First, we are poisoned and muted

status = StatusEffect.Poison | StatusEffect.Mute;

 

//But now we want to remove just the poison, and leave him mute!

status &= ~StatusEffect.Poison;

最后如果我们检测发现如果一个玩家在if语句中,我们可以使用&操作符来查看一个特定的位值:


1

2

3

4

5

//Let‘s check if we are poisoned:

if ((status & StatusEffect.Poison) == StatusEffect.Poison)

{

    //Yep, definitely poisoned!

}

扩展阅读

我不想此文全讲解位标志和位操作,因此我只是简要解释了下。但是如果你不了解位操作,我强烈建议你弄懂它们并制定如何使用。

我个人喜欢维基百科的这个网页:

http://en.wikipedia.org/wiki/Bitwise_operation

同时,System.Flags标记的枚举不会直接在Unity的查看其中正确显示,它们不会让你选择设置某个标记的,之后以非标记的枚举类型显示。但庆幸的是,你可以自己写一个自定义的属性着色器来解决,之后我会在此文追加的!

https://docs.unity3d.com/Documentation/ScriptReference/PropertyDrawer.html

快乐编码!

原文链接:Enums and Flags

Unity中的枚举和标志

时间: 2024-08-11 18:25:47

Unity中的枚举和标志的相关文章

【《Effective C#》提炼总结】提高Unity中C#代码质量的22条准则

本文由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/53869998 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 引言 我们知道,在C++领域,作为进阶阅读材料,必看的书是<Effective C++>. 而<Effective C#>之于C# ,是类似<Effective C++>之于C++一样的存在. 这篇文章,

unity中使用FingerGestures插件3.0

FingerGestures是一个unity3D插件,用来处理用户动作,手势. 译自FingerGestures官方文档 目录 FingerGestures包结构 FingerGestures例子列表 设置场景 教程:识别一个轻敲手势 教程:手势识别器 教程:轻击手势识别器 教程:拖拽手势识别器 教程:滑动手势识别器 教程:长按手势识别器 教程:缩放手势识别器 教程:旋转手势识别器 教程:自定义手势识别器 教程:识别手势事件 建议:使用.net代理事件 fingerGestures包结构 路径,

在Unity中使用贝塞尔曲线(转)

鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是起点,一个是终点.在这条曲线之上还会有两个可以任意移动的点来控制贝塞尔曲线的角度.如下图所示,点1 和点4 就是起点和终点,点2 和点3 就是控制曲线角度的两个动态点. 如下图所示.使用拖动条来让曲线发生旋转,大家会看的更加清晰.目前我们看到的被塞尔曲线是在平面中完成的,其实贝塞尔曲线是完全 支持3

Unity中2D和UGUI图集的理解与使用

图集 什么是图集? 在使用3D技术开发2D游戏或制作UI时(即使用GPU绘制),都会使用到图集,而使用CPU渲染的2D游戏和UI则不存在图集这个概念(比如Flash的原生显示列表),那么什么是图集呢?准确的说法图集是一张包含了多个小图的大图和一份记录了每个小图id.位置.尺寸等数据的数据文件,一个图集应该对应两个文件,当然也有人把数据集成到图片中,导致看起来只有一张图片(参考自DragonBones的做法). 为什么要用图集? 在GPU已经成为PC.手机等设备的必备组件的现在,把所有显示的绘制操

关于用暴风SDK在unity中加入VR效果和利用暴风手柄进行操作

首先在暴风魔镜开发平台下载SDK.地址:http://open.mojing.cn/sdk/download?pid=2  下载unity的工具 MojingSDK., 然后我用的是unity5.42的版本然后将SDK导入unity中.文件夹中包含 接口说明文档说的也比较清楚. 在unity中搭建一个简单的场景需要放入Prefab的MojingMain.并将场景摄像机放入其中并挂上MojingEye脚本 Eye枚举选项为Center 并且添加prefab Overlay. 如果要进行手柄UI交互

NGUI研究院之在Unity中使用贝塞尔曲线(六)[转]

鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是起点,一个是终点.在这条曲线之上还会有两个可以任意移动的点来控制贝塞尔曲线的角度.如下图所示,点1 和点4 就是起点和终点,点2 和点3 就是控制曲线角度的两个动态点. 如下图所示.使用拖动条来让曲线发生旋转,大家会看的更加清晰.目前我们看到的被塞尔曲线是在平面中完成的,其实贝塞尔曲线是完全支持3D

Unity中的协程(一)

这篇文章很不错的问题,推荐阅读英文原版: Introduction to Coroutines Scripting with Coroutines   这篇文章转自:http://blog.csdn.net/huang9012/article/details/38492937 协程介绍 在Unity中,协程(Coroutines)的形式是我最喜欢的功能之一,几乎在所有的项目中,我都会使用它来控制运动,序列,以及对象的行为.在这个教程中,我将会说明协程是如何工作的,并且会附上一些例子来介绍它的用法

NGUI研究之在Unity中使用贝塞尔曲线

鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么我迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是起点,一个是终点.在这条曲线之上还会有两个可以任意移动的点来控制贝塞尔曲线的角度.如下图所示,点1 和点4 就是起点和终点,点2 和点3 就是控制曲线角度的两个动态点.上一章分享了开发项目的一些使用心得比较细节对新手很有用可以看下. 如下图所示.使用拖动条来让曲线发生旋转,大家会看的更加清晰.目前我们看到

【Unity游戏开发】用C#和Lua实现Unity中的事件分发机制EventDispatcher

一.简介 最近马三换了一家大公司工作,公司制度规范了一些,因此平时的业余时间多了不少.但是人却懒了下来,最近这一个月都没怎么研究新技术,博客写得也是拖拖拉拉,周六周天就躺尸在家看帖子.看小说,要么就是吃鸡,唉!真是罪过罪过.希望能从这篇博客开始有些改善吧,尽量少玩耍,还是多学习吧~ 好了扯得有点远了,来说说我们今天博客的主题——“用C#和Lua实现Unity中的事件分发机制”,事件分发机制或者叫事件监听派发系统,在每个游戏框架中都是不可或缺的一个模块.我们可以用它来解耦,监听网络消息,或者做一些