Blender & Godot 3D 教程 - 2026-06-29 - Godot 4 GDScript 基础零基础入门:变量 / 信号 / 生命周期,写一个会响应点击的 3D 小球
零基础打开 Godot 4.6 GDScript:彻底搞懂变量(var / @export / @onready)、信号(signal 的 emit / connect)、生命周期(_ready / _process / _physics_process / _input / _unhandled_input)三大基石,写一个「鼠标点击地面就在那个位置生成 3D 小球、点小球就让它跳一下」的完整 Demo。

Godot 4 GDScript 基础零基础入门:变量 / 信号 / 生命周期,写一个会响应点击的 3D 小球
写在前面
如果你一路跟过这个系列,应该已经被我甩了一脸 GDScript 代码:
- 06-18「3D 基础」里写过
extends Node3D和var speed := 5.0 - 06-20「3D 物理」里写过
_physics_process(delta)和move_and_slide() - 06-24「动画系统」里写过
Tween.new() - 06-26「着色器」里写过
shader_parameter/... - 06-28「联机大厅」里写过
signal room_ready_changed和await
但我从来没单独一篇正经讲过 GDScript 这个语言本身。今天补上这一课。
我们要一次性讲清三块基石——变量 / 信号 / 生命周期——并且每块都配一个能跑的小 Demo,最后合起来做一个完整的东西:
鼠标左键点地面 → 在那个位置生成一个会自转的小球;鼠标左键点小球 → 小球弹一下。
不需要任何前置知识,会打开 Godot 编辑器就行。
小贴士 · 为什么是这三块?
GDScript 语法糖很多(运算符、字典、lambda),但 90% 的「看不太懂」都来自这三块:变量作用域搞不清、信号回调没连上、_ready/_process啥时候跑不明白。把这三块看明白,剩下的都是顺水推舟。
一、准备:建一个新项目
1.1 创建项目
- 打开 Godot 4.6
- 右上角点 New Project
- Project Name:填
gdscript_basics - Project Path:随便选个空目录(不要选到已有项目里)
- Renderer:保持默认 Forward+ 就行
- 点 Create & Edit
小贴士 · Forward+ vs Mobile vs Compatibility
Forward+ 是 Godot 4 的现代渲染管線,支持全套特性(SSIL、Volumetric Fog、glow)。Mobile 适合手机平台、Compatibility 是 GLES3 老显卡兜底。零基础教程一律 Forward+,等你做发布版本时再换。
1.2 检查项目设置
顶部菜单 → Project → Project Settings…
左侧找 Advanced Settings(齿轮图标)打开,找到:
- Physics / Common / Physics Ticks Per Second:默认
60 - Rendering / Environment / Default Clear Color:默认
#373a3f(深灰蓝)
不用改,但记一下位置。
二、第一块基石:变量
2.1 第一个脚本:Hello, GDScript!
- Scene 面板(左上角)→ 点 + 加号按钮 → 选 Other Node → 选 Node → 改名为
Main - 选中
Main节点,按 Ctrl+S 保存场景到scenes/main.tscn - 选中
Main节点,点击右上角 Inspector 旁边的 Script 子标签 → 点 + Create a Script 按钮 - 弹窗里 Path 改成
scripts/main.gd→ 点 Create - 编辑器自动打开
main.gd,里面是:
| |
小贴士 ·
extends Node是什么?
GDScript 里extends= 「这个脚本将挂在一个 Node 类型的对象上」。你后面做 3D 小球会写extends Node3D,做 UI 控件会写extends Control。第一行决定了你能用什么 API。
2.2 变量的三种「身份」
把 main.gd 改成下面这样:
| |
怎么验证?
- 保存(Ctrl+S)
- 回到
main.tscn选中Main节点,看右侧 Inspector 应该出现 Script Variables 一节 - 你会看到
Ball Color(带颜色拾取器)、Ball Radius(拖滑块)、Max Balls(0.1 到 10.0 范围限制)三个字段 - 试着把
Ball Color改成青色,不重启场景就能直接预览
小贴士 · 为什么 @onready 重要?
普通var label: Label = $HUD/CountLabel在脚本加载时立刻执行,但此时HUD子节点可能还没进场景树,会拿到 null 报错。@onready等价于「等_ready()触发了再求值」,是零基础最容易踩的坑之一。
改完后按 F5 运行,Output 面板(底部)应该空——因为现在没打印任何东西。
2.3 类型推断 :=
GDScript 4 全面支持类型推断,省去重复声明:
| |
不用写 : int、: String,但写也不报错。团队代码里建议显式写类型,方便别人阅读。
2.4 常见坑点 #1:忘加 $ 符号
| |
三、第二块基石:生命周期
3.1 生命周期全景图
Node 类有一组特殊的虚函数,Godot 在特定时刻自动调用它们。你只需要「重写」(写一个同名函数),就能在那个时刻插入自己的逻辑。
| 函数名 | 何时被调用 | 一帧调用几次 | 典型用途 |
|---|---|---|---|
_init() | 节点创建时(最早) | 只 1 次 | 初始化成员变量 |
_ready() | 节点和子节点都进场景树 | 只 1 次 | 拿子节点引用、连信号 |
_process(delta) | 每渲染帧 | 60 次/秒(视帧率) | 处理输入、UI 更新、转非物理的东西 |
_physics_process(delta) | 每物理 tick | 固定 60 次/秒 | 移动 RigidBody、处理碰撞 |
_input(event) | 每帧,最早收到输入 | 60 次/秒 | 想最先拦截输入 |
_unhandled_input(event) | UI 没消化掉的输入 | 60 次/秒 | 3D 场景里最常用 |
_exit_tree() | 节点离开场景树 | 只 1 次 | 清理、保存 |
小贴士 · 为什么要有两个 process?
渲染帧率会波动(屏幕 144Hz 就 144 次/秒),但物理 tick 永远是 60 次/秒。如果在_process里移动角色、检测碰撞,会出现「跑得快的玩家穿透墙」的诡异 bug。物理相关的东西必须在_physics_process里做。
3.2 实战:让场景动起来
把 main.gd 改成:
| |
保存 → F5 运行,Output 会打印:
🟢 _ready: 节点刚准备好
🟢 当前帧率上限: 0
但 rotate_y 那行会报红字:Function "rotate_y()" not found in base self。
为什么?因为你 extends Node,而 rotate_y() 是 Node3D 的方法。
修复:把 Main 节点改成 Node3D
- 选中
Main节点 → Inspector 顶部 Type 旁边点 change type 图标 → 选 Node3D → Change - 顶部菜单 → File → Save Scene → Ctrl+S
再 F5,应该没报错。但你也看不到任何东西,因为场景里没相机没光。
3.3 给场景加相机 + 光
回到 main.tscn:
- + Node3D → 选 Camera3D → 改名
Camera - 选中
Camera,右侧 Inspector → Transform / Position → 改成(0, 5, 10) - 选中
Camera,Inspector → Transform / Rotation → 改成(-30, 0, 0)度 - + Node3D → 选 DirectionalLight3D → 改名
SunLight
按 F5,应该看到一个深灰蓝的天空,地面朝下没东西(因为还没放 mesh)。
3.4 常见坑点 #2:相机被遮蔽 / 看不到东西
最常见三种:
- 相机朝向不对:选中 Camera,看场景视图里预览框朝向哪儿
- 相机太近:Position 改成
(0, 5, 10)这种「俯视斜后方」最稳 - 场景里没光源:DirectionalLight3D 看不到「光」本身,但能照亮物体;不旋转它默认从 Z+ 方向照下(默认方向是
(0, -1, 0))
四、第三块基石:信号
信号是 Godot 最独特的范式——一个节点「喊一嗓子」,所有「关注」它的节点都能听见。
4.1 信号的生命周期
节点 A ──emit_signal("name")──> Godot ──call──> 所有 connect("name", obj, "method") 的回调
四步走:
- 声明信号:
signal my_signal(arg1, arg2) - 发射信号:
my_signal.emit(value1, value2) - 连接信号:在另一个节点里
node_a.my_signal.connect(_on_my_signal) - 接收信号:
func _on_my_signal(arg1, arg2) -> void:
4.2 实战:HUD 显示点击次数
4.2.1 建 UI 节点
- 选中
Main→ + Control → 改名HUD - 选中
HUD→ + Label → 改名CountLabel - 选中
CountLabel→ Inspector → Layout / Anchors Preset → 点 top-left 那格(左上角图标) - 选中
CountLabel→ Inspector → Text → 改成Clicks: 0 - Ctrl+S 保存
4.2.2 声明 + 发射信号
改 main.gd:
| |
保存 → F5,控制台暂时不会打印,因为现在没小球发信号——下一步加。
4.3 完整 Demo:点击地面生成小球 + 点小球弹一下
新建脚本 scripts/ball.gd:
| |
新建 scripts/spawner.gd:
| |
把脚本和场景拼起来:
Main (Node3D)Camera (Camera3D)position(0, 5, 10), rotation(-30, 0, 0)SunLight (DirectionalLight3D)Ground (StaticBody3D)Mesh (MeshInstance3D)→ Mesh 属性 → New BoxMesh,Size(20, 0.2, 20),位置(0, -0.1, 0)Collision (CollisionShape3D)→ Shape → New BoxShape3D,Size(20, 0.2, 20)
Spawner (Node3D)挂scripts/spawner.gdHUD (Control)CountLabel (Label)
配置 Spawner:
- 把
Ball做成单独场景:新建scenes/ball.tscn,根节点Node3D,挂scripts/ball.gd - 在
ball.tscn里加MeshInstance3D(New SphereMesh,Radius 0.5),加CollisionShape3D(New SphereShape3D,Radius 0.5) - Ctrl+S 保存
- 回到
main.tscn,选中Spawner,Inspector → Ball Scene → 点 Load → 选scenes/ball.tscn
F5 运行:
- 鼠标点地面 → 新小球生成在点击位置
- 鼠标点小球 → 小球跳一下 + 顶部计数 +1
- Output 面板打印
🟡 信号收到,被点的是: @Node3D@42
🎉 第一个完整的「事件驱动」3D Demo 跑起来了。
小贴士 · 为什么用 _unhandled_input 而不是 _input?
_input最先收到,但 UI(Control 节点)会先消化鼠标事件。如果你写在_input里点按钮也会触发 3D 逻辑,UI 就会「漏点」。_unhandled_input= 「UI 不要的我才要」,是 3D 场景里的最佳实践。
五、常见坑点 #3 大汇总
5.1 信号忘了 connect,永远不触发
| |
症状:运行不报错,但回调函数永远不跑。
解决:在另一个节点的 _ready() 里 connect,并且确认那个节点还在场景树里。
5.2 _process 里移动 RigidBody
| |
症状:角色抖动、穿墙、不响应重力。
解决:移动物理体用 _physics_process(delta),或者用 move_and_slide()(CharacterBody3D 专用)。
5.3 @export 改完不生效
| |
原因:99% 是你没保存场景。Inspector 里改完要 Ctrl+S,否则下次加载场景用旧的 .tscn 文件覆盖。
六、延伸阅读
Godot 官方文档 — GDScript 基础:https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html
权威 reference,遇到语法疑问第一站。Godot 官方文档 — 信号:https://docs.godotengine.org/en/stable/tutorials/scripting/singletons_autoload.html
除了 connect/emit,还讲了 Autoload 单例与信号组合的高级用法。GDQuest — GDScript Fundamentals(YouTube 免费课):https://www.youtube.com/watch?v=UcdwP2eKLtI
视频讲解 + 实战,对零基础读者特别友好。
软件版本 & 数据来源
- Godot 引擎:4.6 stable(2026-06 月度 release)
- GDScript 版本:4.x(Godot 4 内置)
- 教程实操日期:2026-06-29
- 数据来源:Godot 官方文档 4.6、GDQuest 公开教程、笔者实操截图
下一步预告:明天 06-30 我们会讲 Godot 4 UI 与 3D 场景交互(Control + SubViewport + Camera 切换)——给今天的「点击生成小球」加一个右上角小地图,让 3D 场景里嵌一个会动的 2D 雷达。零基础读者特别期待的功能,敬请关注。
— breeze