GDScript 入门笔记(二):变量与数据类型

上一节聊了 GDScript 是什么,这篇正式进入语法。变量和数据类型是写脚本的第一道坎,好消息是 GDScript 的变量系统比 C# 宽松得多,写起来很顺手,但也有一些自己的规则和坑,需要单独搞清楚。

一、用 var 声明变量

GDScript 里声明变量不用写类型,直接 var 名字 = 值 就行。

gdscript 复制代码
var health = 100
var speed = 5.5
var player_name = "Tom"
var is_alive = true

从这些例子能看出来,变量的类型由赋给它的值自动决定。100 是整数,所以 healthint5.5 是浮点数,所以 speedfloat;带引号的是字符串,所以 player_nameStringtruefalse 是布尔值,所以 is_alivebool

这种"不写类型,让编译器猜"的方式在 GDScript 里叫动态类型 。它省事,但有个小问题:变量的类型在运行时才确定,有时候编辑器没法提前帮你发现类型错误。比如你写 health = "一百",编辑器不会在写的时候就报错,要等运行到这一行才崩。不过 Godot 4 对这种动态类型的检查已经比 3 代好了不少,至少会给出警告。

二、基础数据类型

GDScript 的基础类型就几种,下面分别过一下。

1. int(整数)

就是整数,正负都行,没有小数点。

gdscript 复制代码
var age = 25
var enemies = 10

注意 GDScript 的 int 是 64 位有符号整数,范围比 C# 的 int(32 位)大得多,基本不用担心溢出。

2. float(浮点数)

带小数点的数字。在 GDScript 里,只要数里有小数点,就是 float

gdscript 复制代码
var pi = 3.14
var gravity = 9.8

有一点和 C# 不一样:C# 里写 float f = 5.0f 要加后缀 f,GDScript 不用,直接写 5.0 就是浮点数。写 5 就是整数,别搞混。

3. bool(布尔值)

只有 truefalse 两个值。条件判断、开关状态都靠它。

gdscript 复制代码
var can_jump = true
var has_key = false

4. String(字符串)

字符串用双引号或单引号都可以,但习惯上双引号多。

gdscript 复制代码
var name = "Godot"
var msg = '你好'

字符串支持拼接,可以用加号,也可以用 %format() 格式化,后面讲字符串操作时细说。

三、Godot 特有的内置类型

除了基础类型,Godot 还内置了一堆和游戏开发密切相关的类型,比如向量、颜色、变换等。这些在写游戏逻辑时用得非常多。

1. Vector2 和 Vector3

Vector2 表示 2D 坐标或二维向量,Vector3 表示 3D 坐标或三维向量。它们都是结构体类型,直接赋值即可。

gdscript 复制代码
var pos2 = Vector2(100, 50)
var pos3 = Vector3(1.0, 2.0, 3.0)

也可以分别访问分量:

gdscript 复制代码
var pos = Vector2(3, 4)
var x = pos.x  # 3
var y = pos.y  # 4

2D 游戏里,物体的位置、移动方向基本都是 Vector2;3D 则是 Vector3。后面写移动和碰撞时几乎离不开它们。

2. Color(颜色)

表示 RGBA 颜色,常用在调制颜色、粒子颜色等。

gdscript 复制代码
var red = Color(1, 0, 0)        # 红色,不透明
var translucent = Color(1, 1, 1, 0.5)  # 半透明白

Godot 还提供了一些预设颜色常量,比如 Color.REDColor.GREEN 等。

3. 其他常用类型

  • Transform2D / Transform3D:变换矩阵,通常在处理节点位置旋转缩放时内部使用。
  • Rect2:矩形,常用于碰撞区域、UI 布局。
  • AABB:3D 轴对齐包围盒。
  • ArrayDictionary:复合类型,下面单独讲。

这些类型不用死记,用到的时候按 F1 查就行。

四、复合类型:数组与字典

数组和字典是 GDScript 里最常用的两个容器,和 C# 的 List<T> / Dictionary<K,V> 类似,但语法更接近 Python。

1. Array(数组)

数组用方括号 [] 创建,里面可以放任意类型的元素,甚至混合类型。

gdscript 复制代码
var numbers = [1, 2, 3, 4]
var mixed = [1, "two", 3.0, true]

访问元素用下标,从 0 开始:

gdscript 复制代码
var first = numbers[0]  # 1

数组有很多内置方法,比如 append() 添加元素、size() 获取长度、remove() 删除等。这个后面专门有篇笔记展开讲。

2. Dictionary(字典)

字典用花括号 {} 创建,以键值对的形式存储数据。

gdscript 复制代码
var player = {
    "name": "Tom",
    "health": 100,
    "position": Vector2(10, 20)
}

访问值用中括号加键:

gdscript 复制代码
var hp = player["health"]  # 100

字典特别适合存储结构化数据,比如从 JSON 解析出来的配置表。不过 GDScript 的字典是动态类型,访问不存在的键会返回 null 而不是报错,要留意。

五、类型推断与类型注解

前面说过 GDScript 默认是动态类型,但 Godot 4 引入了更强大的类型系统,允许你显式指定变量类型。

1. 类型推断

即使你不写类型,Godot 也会在编译时尽量推断。比如:

gdscript 复制代码
var speed = 5.5   # 推断为 float
var name = "Tom"  # 推断为 String

写的时候体验和动态类型一样,但 Godot 会记录下来,编辑时能给你更好的代码提示。

2. 类型注解

如果你想明确指定类型(也叫静态类型),可以在变量名后面加冒号和类型名:

gdscript 复制代码
var speed: float = 5.5
var name: String = "Tom"
var pos: Vector2 = Vector2.ZERO

一旦写了类型注解,这个变量的类型就固定了。以后给它赋其他类型的值,编辑器会直接报错。

gdscript 复制代码
var health: int = 100
health = "一百"  # 报错:无法将 String 赋值给 int

类型注解的好处:

  • 编辑器补全更准确
  • 编译时能捕获更多错误
  • 运行性能更好(GDScript 的静态类型在运行时更快)

我的习惯是:对于关键变量、成员变量,尽量写类型注解;临时局部变量可以根据情况省略。这样既保留灵活性,又能在重要地方获得保障。

六、常量与 @export 变量

1. const 常量

常量用 const 声明,必须在声明时赋值,之后不能改。

gdscript 复制代码
const MAX_HEALTH = 100
const GRAVITY = 9.8

常量的值在编译时就确定了,所以不能写成运行时才计算的值,比如 const random_value = randf() 会报错。

2. @export 暴露到检查器

在 Unity 里,把变量设为 public 或加 [SerializeField] 就能在 Inspector 里看到并调整。Godot 对应的做法是加 @export 注解。

gdscript 复制代码
extends Node2D

@export var move_speed: float = 100.0
@export var max_health: int = 5

这样 move_speedmax_health 就会出现在节点的 Inspector 面板里,你可以在编辑器中直接改数值,不用动代码。这个功能特别适合调参,比如移动速度、跳跃力度、敌人血量等。

注意:@export 只能用于脚本的成员变量,不能用于局部变量。而且如果变量没有类型注解,Godot 会尝试推断,但最好还是手动指定类型。

七、null 与空值判断

GDScript 里用 null 表示空值,类似 C# 的 null。没有赋值的变量,如果是基础类型(如 intfloatbool)会有默认零值;如果是引用类型(如节点、数组、字典)则默认为 null

gdscript 复制代码
var player = null

判断一个变量是否为空:

gdscript 复制代码
if player == null:
    print("玩家不存在")

Godot 4 还提供了 is null 的写法,但和 == null 等价,看个人习惯。

要注意的是,访问 null 对象的属性或方法会报运行时错误,比如:

gdscript 复制代码
player.health = 100  # 如果 player 是 null,会报错

所以在操作可能为空的节点引用时,先判空是好习惯。

八、写个简单例子感受一下

这里用一个完整的脚本片段结束本篇,展示变量和类型在实际节点脚本中的使用:

gdscript 复制代码
extends Node2D

# 暴露到检查器的变量
@export var move_speed: float = 200.0
@export var jump_force: float = 400.0

# 私有变量
var velocity: Vector2 = Vector2.ZERO
var is_on_floor: bool = false

func _ready():
    # 初始化
    velocity = Vector2.ZERO
    print("初始化完成")

func _process(delta):
    # 读取输入并处理移动(后面输入篇细讲)
    # 注意:这四个动作需要在项目设置 -> 输入映射中手动定义
    var input_dir = Input.get_vector("left", "right", "up", "down")
    velocity = input_dir * move_speed
    position += velocity * delta

在这个例子里,move_speed 用了 @export 和类型注解,velocityVector2 类型,delta_process 自带的时间参数。这些都是 GDScript 变量使用的典型场景。

九、总结

GDScript 的变量系统比 C# 灵活,写起来省事,但也别完全放飞。我的建议是:

  • 基础类型和内置类型要记熟,尤其是 Vector2Vector3Color
  • 关键变量加类型注解,能提前发现错误。
  • 需要调参的变量加 @export,方便在编辑器里调整。
  • 操作可能为空的引用时先判空。
相关推荐
蒸蒸yyyyzwd1 小时前
CPP选手秋招准备学习笔记day25
笔记·学习
摇滚侠2 小时前
《SpringBoot 3:入门与应用实战》第 13 章 整合 MyBatis 使用 MyBatis-Plus 阅读笔记 40
spring boot·笔记·mybatis
INS_KF11 小时前
【编程笔记】成员函数中两个 const 的区别(const Data &getData() const;)
前端·javascript·笔记
tju新生代魔迷12 小时前
Verilog HDL 学习笔记(十三)| 第13章 编程语言接口(PLI)
笔记·学习
点心的游戏开发世界14 小时前
UnityShaderGraph滚动UV笔记
笔记·uv
瑞码空间14 小时前
git知识点黄金笔记
笔记·git·elasticsearch
天若有情67315 小时前
Node+MySQL小型全栈笔记项目实战课程分享
数据库·笔记·mysql
摇滚侠18 小时前
《SpringBoot 3:入门与应用实战》第 12 章 JDBC 与事务 JDBC 事务管理 阅读笔记 33
spring boot·笔记·后端
Wendy不吃榴莲18 小时前
# AI短剧教程 - 《后西游记》开播后,AI影视为什么更考验“连续讲故事”?
人工智能·笔记·学习·ai·视频