译林军 宿学龙|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中的枚举和标志的更多相关文章

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

    作者:Williammao, 腾讯移动客户端开发工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. 原文链接:http://wetest.qq.com/lab/view/290.h ...

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

    引言 原则1尽可能地使用属性而不是可直接访问的数据成员 原则2偏向于使用运行时常量而不是编译时常量 原则3 推荐使用is 或as操作符而不是强制类型转换 原则4 推荐使用条件属性而不是if条件编译 原 ...

  3. 【转】Effective C#观后感之提高Unity中C#代码质量的21条准则

    转自:http://blog.csdn.net/swj524152416/article/details/75418162 我们知道,在C++领域,作为进阶阅读材料,必看的书是<Effectiv ...

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

    鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是 ...

  5. .NET中的枚举(Enum)

    摘要:.NET中的枚举分为简单枚举和标志枚举,这次主要总结一下标志枚举适用条件,以及它的使用方法,并在文章的最后列举枚举使用的一些规范. 在刚接触.NET的枚举时,只用简单的枚举,对于标记枚举,只知道 ...

  6. Unity中的协程(一)

    这篇文章很不错的问题,推荐阅读英文原版: Introduction to Coroutines Scripting with Coroutines   这篇文章转自:http://blog.csdn. ...

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

    鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是 ...

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

    图集 什么是图集? 在使用3D技术开发2D游戏或制作UI时(即使用GPU绘制),都会使用到图集,而使用CPU渲染的2D游戏和UI则不存在图集这个概念(比如Flash的原生显示列表),那么什么是图集呢? ...

  9. c#中[Flags] 枚举类型定义问题_百度知道

    [Flags]的微软解释是“指示可以将枚举作为位域(即一组标志)处理.”其实就是在编写枚举类型时,上面附上Flags特性后,用该枚举变量是既可以象整数一样进行按位的“|”或者按位的“&”操作了 ...

随机推荐

  1. 在Ubuntu18.04系统里面安装VMware tools遇到的问题 以及解决办法

    问题1:Ubuntu18.4下安装VMware Tools 一直提示 “what is the location of the ifconfig program on your manchine”. ...

  2. 数据分析First week(7.15~7.21)

    描述统计学 当我们面对大量信息的时候,经常会出现数据越多,事实越模糊的情况,因此我们需要对数据进行简化,描述统计学就是用几个关键的数字来描述数据集的整体情况. 1.集中趋势 1.1 众数 众数是样本观 ...

  3. 为写程序而生的连字字体 Fira Code

    Fira Code,等宽的编程连字字体 **等宽 ** 是指所有字符的宽度相同,如: W 和 i 用一样的宽度去显示 连字(ligatures)为文字排印的一个特性,比如「f」和「 i」放在一起的时候 ...

  4. 004_自己尝试go语言中的方法

    go语言可以给任意类型定义方法,我在学习过程中,一开始一头雾水,但是随着理解的深入,现在也大概知道了什么叫做方法 之前的一些例子其实讲的并不是特别生动,下面我用一个生动的例子演示一下 首先提出需求.我 ...

  5. java流程控制语句switch

    switch 条件语句也是一种很常用的选择语句,它和if条件语句不同,它只能针对某个表达 式的值作出判断,从而决定程序执行哪一段代码. 格式: switch (表达式){ case 目标值1: 执行语 ...

  6. 论如何实现最强大脑黑白迭代(c++附代码)

    最近看了最强大脑,对节目中的黑白迭代很感兴趣,就自己写了一个500多行的程序.燃鹅,只实现了一部分功能,还非常简陋.无奈之下,我只好从网上下载了一份代码,然后自己稍加修改就成了一份半改编的代码. 虽然 ...

  7. 高吞吐量消息系统—kafka

    现在基本上大数据的场景中都会有kafka的身影,那么为什么这些场景下要用kafka而不用其他传统的消息队列呢?例如rabbitmq.主要的原因是因为kafka天然的百万级TPS,以及它对接其他大数据组 ...

  8. python设计模式之修饰器模式

    python设计模式之修饰器模式 无论何时我们想对一个对象添加额外的功能,都有下面这些不同的可选方法. [ ] 如果合理,可以直接将功能添加到对象所属的类(例如,添加一个新的方法) [ ] 使用组合 ...

  9. 【UVa1635】Irrelevant Elements - 唯一分解定理

    题意 给你 \(n\) 个数,每次求出相邻两个数的和组成新数列.经过 \(n-1\) 次操作后,得到一个数.求这个数 \(mod \ m\) 与哪些项无关. 如:当 \(m=2 \ , \ n=2\) ...

  10. 【ZJOI 2008】 树的统计 - 树链剖分

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...