Unity的C#编程教程_58_Enums 详解及应用练习

C# Enums: Introduction

  • 枚举的作用
    • 设定可读取的选项
    • 不同的选项用 integer 表示

传统的做法是,设计一个变量进行指示,比如 0 代表简单,1 代表普通,2 代表困难,然后配合上判断语句。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SelectDifficulty : MonoBehaviour
{

    public int easy = 0;
    public int normal = 1;
    public int hard = 2;
    public int selectedDifficulty;


    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

另外一种更直观的方法应该是,有个下拉列表 dropdown list,可以选择0,1,2,分别对应 3 个难度等级。

比如设计一个难度选择脚本 SelectDifficulty,挂载到 main camera 上:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SelectDifficulty : MonoBehaviour
{

    public enum DifficultySelector
    {
        Easy, // 自动分配为 0,也可以手动设置指定的数值比如 Easy=13,
        Normal, // 自动分配为 1
        Hard // 自动分配为 2
    }

    public DifficultySelector selectedDifficulty; // 生成一个下拉框

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

这样在 inspector 中就可以看到一个 Selected Difficulty 的下拉框,里面的选项是 Easy,Normal,Hard。

然后程序中就可以设置对应的分支了:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SelectDifficulty : MonoBehaviour
{

    public enum DifficultySelector
    {
        Easy, // 自动分配为 0,也可以手动设置指定的数值比如 Easy=13,
        Normal, // 自动分配为 1
        Hard // 自动分配为 2
    }

    public DifficultySelector selectedDifficulty;

    // Start is called before the first frame update
    void Start()
    {
        /* 
        if(selectedDifficulty == DifficultySelector.Easy)
        {
            Debug.Log("Easy level");
        }
        else if(selectedDifficulty == DifficultySelector.Normal)
        {
            Debug.Log("Normal level");
        }
        else if(selectedDifficulty == DifficultySelector.Hard)
        {
            Debug.Log("Hard level");
        }
        */

        // 我们可以使用 if 判断语句,但是更常用的搭配是 switch语句
        switch (selectedDifficulty)
        {
            case DifficultySelector.Easy:
                Debug.Log("Easy level");
                break;

            case DifficultySelector.Normal:
                Debug.Log("Normal level");
                break;

            case DifficultySelector.Hard:
                Debug.Log("Hard level");
                break;
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

C# Enums: Enemy AI

  • 使用 Enum 来设计 Enemy AI
    • FSM:finite state machine
    • 敌人的不同状态:比如巡逻模式,攻击模式,死亡状态等

创建一个脚本 EnemyAI:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyAI : MonoBehaviour
{
    public enum EnemyState // 创建一个 enum 来设置敌人的不同状态
    {
        Patroling, // 巡逻状态
        Attacking, // 攻击状态
        Chasing, // 追踪状态
        Death // 死亡状态
    }

    public EnemyState currentState; // 当前状态

    // Start is called before the first frame update
    void Start()
    {
        currentState = EnemyState.Patroling; // 初始化为巡逻状态
    }

    // Update is called once per frame
    void Update()
    {
        switch (currentState)
        {
            case EnemyState.Patroling:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;

            case EnemyState.Attacking:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;

            case EnemyState.Chasing:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;

            case EnemyState.Death:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;
        }
    }
}

创建一个 Capsule 作为 Enemy,然后挂载上该脚本。

这样就有了个切换开关,可以转换 Enemy 的动作状态了。

我们可以设置多个 Enemy,每个 Enemy 在不同情况下激活不同状态。比如默认状态是 Patroling,玩家接近到视野中的时候切换为 Attacking。

这里我们尝试手动切换:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyAI : MonoBehaviour
{
    public enum EnemyState // 创建一个 enum 来设置敌人的不同状态
    {
        Patroling, // 巡逻状态
        Attacking, // 攻击状态
        Chasing, // 追踪状态
        Death // 死亡状态
    }

    public EnemyState currentState; // 当前状态

    // Start is called before the first frame update
    void Start()
    {
        currentState = EnemyState.Patroling; // 初始化为巡逻状态
    }

    // Update is called once per frame
    void Update()
    {
        switch (currentState)
        {
            case EnemyState.Patroling:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;

            case EnemyState.Attacking:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;

            case EnemyState.Chasing:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;

            case EnemyState.Death:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;
        }

        if (Input.GetKeyDown(KeyCode.P)) // 将 Enemy 设定为巡逻模式
        {
            currentState = EnemyState.Patroling;
        }
        else if(Input.GetKeyDown(KeyCode.A)) // 将 Enemy 设定为攻击模式
        {
            currentState = EnemyState.Attacking;
        }
        else if (Input.GetKeyDown(KeyCode.C)) // 将 Enemy 设定为追踪模式
        {
            currentState = EnemyState.Chasing;
        }
        else if (Input.GetKeyDown(KeyCode.D)) // 将 Enemy 设定为死亡状态
        {
            currentState = EnemyState.Death;
        }
    }
}

我们也可以直接在 Switch 中设置切换:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyAI : MonoBehaviour
{
    public enum EnemyState // 创建一个 enum 来设置敌人的不同状态
    {
        Patroling, // 巡逻状态
        Attacking, // 攻击状态
        Chasing, // 追踪状态
        Death // 死亡状态
    }

    public EnemyState currentState; // 当前状态

    // Start is called before the first frame update
    void Start()
    {
        currentState = EnemyState.Patroling; // 初始化为巡逻状态
    }

    // Update is called once per frame
    void Update()
    {
        switch (currentState)
        {
            case EnemyState.Patroling:

                if (Time.time > 5) // 游戏运行 5 秒后转化为攻击模式
                {
                    currentState = EnemyState.Attacking;
                }

                break;

            case EnemyState.Attacking:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;

            case EnemyState.Chasing:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;

            case EnemyState.Death:
                //
                // 这里设置该状态下的 Enemy 的对应逻辑动作
                //
                break;
        }
    }
}

C# Enums: Custom Classes

  • 把 enum 和自定义的类结合起来
    • 为类设置属性的下拉菜单

创建一个脚本命名为 Item:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable] // 在 Inspector 中可见
public class Item
{
    public string name;
    public int id;
    public Sprite icon;

    public enum ItemType // 道具所有类型
    {
        Weapon, // 武器
        Consumable, // 消耗品
        Others // 其他
    }

    public ItemType itemType; // 该道具类型

}

创建一个物品数据库 ItemDatabase:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemDatabase : MonoBehaviour
{
    public List<Item> itemDatabase;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

挂载到 Main Camera 上面,设置 size,然后就可以编辑物品的信息了,其中有个下拉框可以选择物品类型。

不同的类型物品可以有不同的方法使用:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable] // 在 Inspector 中可见
public class Item
{
    public string name;
    public int id;
    public Sprite icon;

    public enum ItemType // 道具所有类型
    {
        Weapon,
        Consumable,
        Others
    }

    public ItemType itemType; // 该道具类型

    public void Action() // 每种道具有不同的使用方法
    {
        switch (itemType)
        {
            case ItemType.Weapon:
                Debug.Log("Attack"); // 武器用来攻击
                break;

            case ItemType.Consumable:
                Debug.Log("Eat"); // 消耗品用来吃
                break;

            case ItemType.Others:
                Debug.Log("Nothing"); // 其他类型无法使用
                break;
        }
    }

}

遍历物品来使用:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemDatabase : MonoBehaviour
{
    public List<Item> itemDatabase;

    // Start is called before the first frame update
    void Start()
    {
        foreach(var item in itemDatabase) // 遍历物品数据库
        {
            Debug.Log(item.name); // 打印物品名字
            item.Action(); // 执行物品对应的动作
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

C# Enums: Casting Enums to Ints

  • 为 enum 的成员指定一个整型数字
    • 可以用来控制场景选择

比如我们要使用 enum 来做关卡选择,除了可以用对应的名字,可以用一个数字来选择

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; // 用于游戏中场景控制的库

public class LevelSelect : MonoBehaviour
{

    public enum Level
    {
        Level_1, // 默认对应 0
        Level_2, // 默认对应 1
        Level_3,
        Level_4
    }

    public Level currentLevel;

    // Start is called before the first frame update
    void Start()
    {
        currentLevel = Level.Level_1; // 初始化为第一关

        // 我们想要进入第一关的场景:
        SceneManager.LoadScene(0);
        // 场景选择的输入需要是个整型数字,所以这里不能传入 currentLevel
        // 所以我们可以改成下面的写法:
        SceneManager.LoadScene((int)currentLevel);
        // 或者下面的写法:
        SceneManager.LoadScene((int)Level.Level_1);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

建立 4 个 Scenes,分别命名为:Level_1~Level_4,选择 File - Build Settings,将 4 个场景文件拖拽到 Scenes In Build 窗口中,点击 Build。

运行游戏后,即进入了 Level_1 的场景。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值