384人加入学习
(0人评价)
GDScript初学者入门教程-基于Godot和AI教学

使用Godot4.6.2 制作完成于2026.5.13

价格 免费

### 4. 枚举 enum

> 配套示例:`examples/04_enum.gd`

枚举用来定义"一组命名常量",比写一堆 `const` 整齐得多。

```gdscript
enum State { IDLE, RUN, JUMP, ATTACK } 

 # 这里的状态 翻译成中文,对应为4个状态,空闲,跑,跳,攻击

var current := State.IDLE

func update_state(s):
    current = s
    match current:
        State.IDLE:    print("在发呆")
        State.RUN:     print("在跑")
        State.JUMP:    print("在跳")
        State.ATTACK:  print("在攻击")
```

也可以显式指定值:

```gdscript
enum Dir { LEFT = -1, RIGHT = 1 }

#枚举类型通常是自动按0,1...取值,但也可以指定数值
```

**底层原理**:枚举值实际就是 int。`State.IDLE` 在内部是 `0`、`State.RUN` 是 `1`,依此类推。

 

## 第 4 节:枚举 enum
##
## 演示用 enum 表示"一组命名常量"。
## 配合 match 写状态分支非常顺手。

extends Node

#int  float  String   这里enum算是一个新的类型,但本质还是int类型
enum State { IDLE, RUN, JUMP, ATTACK }
enum Direction { LEFT = -1, RIGHT = 1 }

var current_state := State.IDLE
var facing := Direction.RIGHT


func _ready() -> void:
    print("当前状态:", current_state)
    print("State.IDLE 实际是数字:", State.IDLE)
    print("State.RUN 实际是数字:", State.RUN)

    current_state = State.RUN
    describe_state()

    current_state = State.ATTACK
    describe_state()

    print("朝向:", facing)


func describe_state() -> void:
    match current_state:
        State.IDLE:
            print("在发呆")
        State.RUN:
            print("在跑")
        State.JUMP:
            print("在跳")
        State.ATTACK:
            print("在攻击")
        _:
            print("未知状态")
 

## 第 4 节附加:为什么要用枚举?
##
## 同一个"角色状态机"分别用 3 种写法实现:
##   方案 A:直接用 int "魔法数字"
##   方案 B:用一堆 const 常量
##   方案 C:用 enum 枚举(推荐)
##
## 把脚本挂到任意 Node 上,F6 运行场景看输出。
## 然后建议你自己改两行代码,体会哪种写法最不容易出错。

extends Node


# =========================================================
# 方案 A:用裸数字(最差写法)
# =========================================================
# 约定:0 = 待机,1 = 跑步,2 = 跳跃,3 = 攻击
# 缺点:
#   1. 看到 "2" 完全不知道是啥
#   2. 写错数字(比如 5)编辑器不会报错
#   3. 以后想在中间插一个新状态,所有数字都要重排
var state_a: int = 0


# =========================================================
# 方案 B:用一堆 const 常量
# =========================================================
# 比 A 好多了,至少看得懂名字。
# 但还是有坑:
#   1. 类型还是 int,state_b = 999 不会报错
#   2. 没"组"的概念,常量列表会越来越乱
#   3. 不能一次性遍历"所有状态"
const STATE_IDLE := 0
const STATE_RUN := 1
const STATE_JUMP := 2
const STATE_ATTACK := 3

var state_b: int = STATE_IDLE


# =========================================================
# 方案 C:用 enum(推荐)
# =========================================================
# 好处:
#   1. State 是独立类型,编辑器有自动补全
#   2. State.RUNN 这种拼写错误会立刻飘红
#   3. 天然有"分组"概念,相关常量挤在一起
#   4. 可以用 State.keys() / State.values() 遍历
enum State { IDLE, RUN, JUMP, ATTACK }

var state_c: State = State.IDLE


func _ready() -> void:
    print("========== 方案 A:裸数字 ==========")
    state_a = 1
    describe_a(state_a)

    # 下面这一行是 bug,但编辑器不会拦你
    state_a = 999
    describe_a(state_a)

    print("\n========== 方案 B:const 常量 ==========")
    state_b = STATE_RUN
    describe_b(state_b)

    # const 也只是 int,这种错误还是逃不掉
    state_b = 999
    describe_b(state_b)

    print("\n========== 方案 C:enum(推荐)==========")
    state_c = State.RUN
    describe_c(state_c)

    state_c = State.ATTACK
    describe_c(state_c)

    # enum 自带遍历能力,A 和 B 都做不到
    print("\n所有状态名:", State.keys())
    print("所有状态值:", State.values())

    # 下面这一行如果取消注释,编辑器会直接飘红
    # state_c = State.RUNN     # ❌ 拼写错误,Godot 立刻报错
    # state_c = 999            # ❌ 类型不匹配,Godot 立刻报错


# ---------------------------------------------------------
# 方案 A 的处理函数:必须靠"魔法数字"判断
# ---------------------------------------------------------
func describe_a(s: int) -> void:
    # 看到这些数字,三个月后的你会一脸懵
    match s:
        0: print("[A] 待机")
        1: print("[A] 跑步")
        2: print("[A] 跳跃")
        3: print("[A] 攻击")
        _: print("[A] 未知状态(值=%d),但编辑器没发现错误" % s)


# ---------------------------------------------------------
# 方案 B 的处理函数:好一点,但还是 int
# ---------------------------------------------------------
func describe_b(s: int) -> void:
    match s:
        STATE_IDLE:   print("[B] 待机")
        STATE_RUN:    print("[B] 跑步")
        STATE_JUMP:   print("[B] 跳跃")
        STATE_ATTACK: print("[B] 攻击")
        _:            print("[B] 未知状态(值=%d)" % s)


# ---------------------------------------------------------
# 方案 C 的处理函数:参数类型就是 State,传错直接报错
# ---------------------------------------------------------
func describe_c(s: State) -> void:
    match s:
        State.IDLE:   print("[C] 待机")
        State.RUN:    print("[C] 跑步")
        State.JUMP:   print("[C] 跳跃")
        State.ATTACK: print("[C] 攻击")
        _:            print("[C] 未知状态")
 

[展开全文]

授课教师

问问题加入A计划,有专门负责答疑的老师哦!!!

课程特色

下载资料(1)
视频(35)