第一部分 01:Godot 基础世界观

2026-05-19
496017 分钟
...

先建立一个总认知:

Godot 做游戏的核心思路是:用一个个 Node 组成 Scene,再把 Scene 放进 SceneTree 运行。代码 Script 负责控制 Node,Resource 负责存数据,Signal 负责对象之间通信。

你可以先把 Godot 想成一个“可视化的前端工程”:

Godot前端类比说明
Project一个前端项目仓库整个游戏工程
Scene一个组件 / 页面 / prefab可复用的对象组合
NodeDOM 节点 / 组件实例游戏里的最小功能单位
Scene Tree当前页面运行时 DOM 树游戏运行时真实存在的节点树
Resource图片、配置、JSON、样式资源被节点使用的数据或资源
ScriptJS / TS 逻辑文件控制节点行为
Signal事件 emit / on节点之间的消息通知

Godot 官方文档里也强调:Node 是 Godot 的构建块,节点可以组成树;一棵节点树就是一个 Scene,Scene 可以保存到磁盘并实例化到其他 Scene 中。 (Godot Engine documentation)

1. Godot 是什么

Godot 是一个开源的游戏引擎,可以做 2D、3D、UI、工具、桌面应用,甚至可以导出到多个平台。它不是一个“库”,而是一个完整编辑器 + 运行时 + 脚本系统 + 资源系统。Godot 当前官方下载页显示最新稳定版为 4.6.2;如果你现在用的是 4.x,下面这些基础概念基本都通用。(Godot Engine)

前端类比

如果前端是这样:

Vue / React 项目
├── 页面
├── 组件
├── 资源
├── 路由
├── 状态
└── 构建配置

Godot 大概是这样:

Godot 项目
├── Scene 场景
├── Node 节点
├── Resource 资源
├── Script 脚本
├── Project Settings 项目配置
└── Export 导出配置

你现在做 RPG、星露谷类似游戏,最常接触的是:

2D 场景
角色节点
地图节点
碰撞节点
摄像机节点
UI 节点
资源文件
脚本逻辑

2. Project:项目是什么

Godot 的 Project 就是整个游戏工程。

一个 Godot 项目一般会有:

my_game/
├── project.godot
├── scenes/
├── scripts/
├── assets/
├── resources/
└── .godot/

常见目录说明

project.godot

这是 Godot 项目的核心配置文件,类似前端里的 package.json + vite.config.ts + 项目配置 的混合体。

.godot/

Godot 自动生成的缓存目录,通常不需要手动改,也一般不提交到 Git。

scenes/

放场景文件,比如:

player.tscn
main.tscn
world.tscn
house.tscn
scripts/

放 GDScript 脚本,比如:

player.gd
camera_controller.gd
weather_manager.gd
assets/

放图片、音频、字体、tileset 等资源。

resources/

放自定义资源,比如角色配置、物品配置、天气配置。

Project 重点理解

项目不是游戏画面本身。

项目只是一个“容器”,真正运行起来的是项目里指定的 主场景 Main Scene

Godot 文档里提到,一个项目可以有很多 Scene,但引擎只需要一个主场景作为程序启动时首先加载的场景。主场景路径会保存到 project.godot 里,也可以通过 Project Settings 修改。(Godot Engine documentation)

前端类比

Godot Project前端项目根目录
Main Scenemain.tsx / App.vue / 根页面
project.godot项目配置文件

比如你做一个 RPG:

Project: FantasyRPG
Main Scene: res://scenes/main.tscn

运行游戏时,Godot 先加载 main.tscn

3. Scene:场景是什么

这是 Godot 里最重要的概念之一。

Scene 不只是“地图场景”。

在 Godot 里,Scene 更像一个“可复用的对象模板”。

它可以是:

一张地图
一个玩家
一个怪物
一个宝箱
一个 UI 面板
一个按钮
一个技能特效
一个天气系统
一个房子内部

Scene 的本质

一个 Scene 本质上是一棵 Node 树。

比如玩家 Scene:

Player CharacterBody2D
├── Sprite2D
├── CollisionShape2D
├── AnimationPlayer
└── Camera2D

这个整体可以保存为:

res://scenes/player.tscn

以后你想在地图里放玩家,不是重新搭一遍,而是把 player.tscn 实例化进去。

前端类比

Scene 很像 Vue / React 组件。

比如前端组件:

<Player>
  <Avatar />
  <HealthBar />
  <Inventory />
</Player>

Godot Scene:

Player
├── Sprite2D
├── CollisionShape2D
├── HealthBar
└── Inventory

但 Godot Scene 比前端组件更“实体化”。

它不仅有 UI,还能有:

位置
碰撞
动画
物理
声音
摄像机
输入处理

Scene 的几个核心特点

1. Scene 有一个根节点

每个 Scene 都必须有一个 root node。

比如:

Main Node2D
├── TileMapLayer
├── Player
├── Camera2D
└── CanvasLayer

这里 Main 就是根节点。

2. Scene 可以嵌套 Scene

比如你的主场景:

Main
├── WorldMap
├── Player
├── WeatherManager
└── UI

其中 Player 可以是另一个 .tscn 文件实例化进来的。

3. Scene 可以重复使用

一个怪物 Scene 可以实例化 100 次。

Slime.tscn

可以生成:

Slime_001
Slime_002
Slime_003
...

这就像前端里同一个组件渲染多个实例。

4. Node:节点是什么

Node 是 Godot 里最小的功能单位。

每个 Node 通常负责一件事。

比如:

节点作用
Node最基础节点,没有 2D/3D 位置
Node2D2D 节点基础类,有位置、旋转、缩放
Sprite2D显示一张 2D 图片
CharacterBody2D2D 角色物理移动
CollisionShape2D碰撞形状
Camera2D2D 摄像机
Label显示文字
Button按钮
AudioStreamPlayer播放声音
AnimationPlayer播放动画

Godot 官方文档把 Node 称为构建块,节点可以作为其他节点的子节点,形成树状结构;同一父节点下的兄弟节点名称需要唯一。(Godot Engine documentation)

前端类比

前端 DOM:

<div class="player">
  <img class="sprite" />
  <div class="health-bar"></div>
</div>

Godot 节点树:

Player CharacterBody2D
├── Sprite2D
├── CollisionShape2D
└── HealthBar Control

前端里一个元素通常只是显示结构。

Godot 里的 Node 通常带有行为能力,比如:

Sprite2D 负责显示
CollisionShape2D 负责碰撞范围
CharacterBody2D 负责角色移动
Camera2D 负责镜头
AudioStreamPlayer 负责声音

Node 的常用属性

Node2D 为例,常见属性有:

position
rotation
scale
visible
z_index

position

节点在父节点坐标系里的位置。

position = Vector2(100, 200)

类似 CSS 里的:

left: 100px;
top: 200px;

但 Godot 里是游戏坐标,不是 DOM 布局。

rotation

旋转角度,单位通常是弧度。

rotation = 1.57

也可以用角度:

rotation_degrees = 90

scale

缩放。

scale = Vector2(2, 2)

visible

是否显示。

visible = false

类似:

display: none;

但注意:隐藏不等于删除,节点仍然存在。

z_index

2D 层级。

z_index = 10

类似 CSS 的:

z-index: 10;

Node 的常用方法

add_child

添加子节点。

add_child(enemy)

类似前端:

parent.appendChild(enemyElement)

get_node

根据路径查找节点。

var sprite = get_node("Sprite2D")

常见简写:

var sprite = $Sprite2D

如果是深层节点:

var hp_bar = $UI/HealthBar

queue_free

删除节点。

queue_free()

它不是立刻粗暴删除,而是排队到安全时机删除。

常用于:

怪物死亡
子弹命中
特效播放结束
临时 UI 关闭

get_parent

获取父节点。

var parent = get_parent()

get_tree

获取当前 SceneTree。

get_tree()

常用于切换场景、暂停游戏、查找分组节点。

5. SceneTree:节点树是什么

SceneTree 是游戏运行时真正存在的节点树。

你在编辑器里看到的是 .tscn 文件的结构。

游戏运行后,Godot 会把场景加载进 SceneTree。

官方文档说,SceneTree 管理节点层级和场景本身,可以添加、获取、删除节点,也可以暂停、切换、重新加载场景;SceneTree 也是 Godot 默认的 MainLoop 实现,负责游戏循环。(Godot Engine documentation)

编辑器里的 Scene 和运行时 SceneTree 的区别

编辑器里:

player.tscn

只是一个资源文件。

运行时:

Player 实例

才是真正活着的对象。

前端类比

前端里:

<Player />

是组件定义。

浏览器运行后:

真实 DOM 节点

才是实际存在的东西。

Godot 里:

Player.tscn

是场景模板。

运行后:

SceneTree 里的 Player 节点实例

才是实际存在的对象。

SceneTree 生命周期

Godot 节点进入 SceneTree 后,才真正“活了”。

官方文档说明,当节点直接或间接连接到 root viewport 后,它就成为 SceneTree 的一部分,并会获得处理输入、显示画面、播放声音、接收通知等能力;移出 SceneTree 后,这些能力也会失去。(Godot Engine documentation)

常见生命周期方法:

func _enter_tree():
    pass

func _ready():
    pass

func _process(delta):
    pass

func _physics_process(delta):
    pass

func _exit_tree():
    pass

生命周期方法解释

_enter_tree

节点进入 SceneTree 时调用。

func _enter_tree():
    print("进入场景树")

注意:这时候子节点不一定都准备好了。

_ready

节点和子节点都准备好之后调用。

func _ready():
    print("准备完成")

常用于初始化:

func _ready():
    $Sprite2D.visible = true

Godot 文档里说明,进入树时父节点的 _enter_tree() 会先于子节点触发,而 _ready() 调用顺序是从子节点往父节点。也就是说:enter 是父到子,ready 是子到父。 (Godot Engine documentation)

_process(delta)

每一帧调用。

func _process(delta):
    position.x += 100 * delta

适合:

动画更新
非物理逻辑
计时
视觉效果
UI 更新

delta 是距离上一帧过去的时间,单位是秒。

比如:

position.x += 100 * delta

表示每秒移动 100 像素,不是每帧移动 100 像素。

_physics_process(delta)

固定物理帧调用。

func _physics_process(delta):
    move_and_slide()

适合:

角色移动
碰撞
物理相关逻辑

角色移动一般优先放这里。

_exit_tree

节点离开 SceneTree 时调用。

func _exit_tree():
    print("离开场景树")

6. Resource:资源是什么

Resource 是 Godot 中用来保存数据的对象。

它本身通常不“干活”,而是被节点使用。

常见 Resource:

Texture2D 图片纹理
AudioStream 音频
PackedScene 打包场景
TileSet 瓦片集
Animation 动画资源
Font 字体
Material 材质
Shader 着色器
自定义 Resource

前端类比

Resource 类似:

图片文件
音频文件
JSON 配置
CSS 变量
组件配置对象
接口 mock 数据

比如:

玩家节点 Sprite2D 使用 Texture2D
地图节点 TileMapLayer 使用 TileSet
音频节点 AudioStreamPlayer 使用 AudioStream

Resource 和 Node 的区别

这是新手很容易混的点。

类型是否在场景树里是否有位置主要作用
Node可能有执行功能、参与游戏
Resource没有保存数据、被节点引用

比如:

Sprite2D Node
Texture2D Resource

Sprite2D 负责“显示图片”。

Texture2D 是“图片数据”。

Resource 的典型例子

图片资源

res://assets/player.png

Sprite2D.texture 使用。

场景资源

res://scenes/player.tscn

PackedScene 加载后实例化。

var player_scene = preload("res://scenes/player.tscn")
var player = player_scene.instantiate()
add_child(player)

这里:

preload("res://scenes/player.tscn")

拿到的是一个 PackedScene 资源。

instantiate()

才生成真正的节点实例。

7. Script:脚本是什么

Script 是挂在 Node 上的代码。

在 Godot 里,脚本不是孤立运行的,它通常依附于某个节点。

比如:

Player CharacterBody2D
└── player.gd

脚本控制这个玩家节点:

extends CharacterBody2D

func _ready():
    print("玩家生成了")

前端类比

Vue 组件:

<script setup>
const speed = 100
</script>

Godot 节点脚本:

extends CharacterBody2D

var speed = 100

你可以理解为:

Node 是结构和能力
Script 是这个 Node 的业务逻辑

extends 是什么

extends CharacterBody2D

表示这个脚本继承自 CharacterBody2D

也就是说,这个脚本会拥有 CharacterBody2D 的能力。

比如:

move_and_slide()
velocity
is_on_floor()

如果写:

extends Node2D

那它就没有角色物理移动能力。

这跟前端类比不完全一样,更像:

class Player extends CharacterBody2D {}

常见脚本结构

extends CharacterBody2D

@export var speed: float = 120.0

@onready var sprite: Sprite2D = $Sprite2D

func _ready():
    print("Player ready")

func _physics_process(delta):
    var direction = Vector2.ZERO

    if Input.is_action_pressed("ui_right"):
        direction.x += 1
    if Input.is_action_pressed("ui_left"):
        direction.x -= 1
    if Input.is_action_pressed("ui_down"):
        direction.y += 1
    if Input.is_action_pressed("ui_up"):
        direction.y -= 1

    velocity = direction.normalized() * speed
    move_and_slide()

重点解释

@export

把变量暴露到 Inspector 面板。

@export var speed = 120

这样你不用改代码,就能在编辑器里调速度。

类似前端组件的 props,但不是完全一样:

<Player speed={120} />

@onready

等节点 ready 后再获取子节点。

@onready var sprite = $Sprite2D

因为脚本刚加载时,子节点可能还没准备好。

Input.is_action_pressed

检测输入动作。

Input.is_action_pressed("ui_right")

注意这里检测的是“动作名”,不是具体键盘按键。

按键绑定在:

Project > Project Settings > Input Map

Godot 的官方 2D 入门教程也是通过 Project Settings 的 Input Map 添加移动动作。(Godot Engine documentation)

8. Signal:信号是什么

Signal 是 Godot 的事件系统。

官方文档说,Signal 是节点在特定事情发生时发出的消息,比如按钮被按下;其他节点可以连接这个信号,并在信号发生时调用函数。Signal 可以让一个游戏对象响应另一个对象的变化,同时减少彼此直接引用。(Godot Engine documentation)

前端类比

前端:

button.addEventListener("click", handleClick)

Vue:

<button @click="handleClick" />

React:

<button onClick={handleClick} />

Godot:

button.pressed.connect(_on_button_pressed)

内置信号

比如 Button 自带 pressed 信号。

func _ready():
    $Button.pressed.connect(_on_button_pressed)

func _on_button_pressed():
    print("按钮被点击了")

编辑器里也可以连接信号:

选中 Button
右侧 Node 面板
Signals
pressed
Connect

Godot 会自动生成类似:

func _on_button_pressed():
    pass

自定义信号

你也可以自己定义信号。

signal health_changed(current_health)

发出信号:

health_changed.emit(80)

连接信号:

player.health_changed.connect(_on_player_health_changed)

响应:

func _on_player_health_changed(current_health):
    print("玩家血量变了:", current_health)

Signal 适合用在哪里

Signal 很适合“我发生了某件事,谁关心谁处理”。

比如:

玩家血量变化UI 更新血条
怪物死亡掉落物品
宝箱打开播放音效
按钮点击切换界面
天气改变地图颜色变化
时间到晚上打开灯光
进入房间区域切换室内音乐

不要这样写

player.ui.health_bar.value = player.health

这会让 Player 强依赖 UI。

更好的方式:

signal health_changed(value)

func take_damage(amount):
    health -= amount
    health_changed.emit(health)

然后 UI 自己监听:

player.health_changed.connect(_on_health_changed)

这就像前端里避免组件乱拿别的组件实例,改用事件或状态流。

第一部分核心心智模型

你先记住这张关系图:

Godot Project
└── Main Scene
    └── Root Node
        ├── Child Node
        ├── Child Node
        └── Instanced Scene
            └── Node
                ├── Script
                ├── Resource
                └── Signal

换成具体 RPG 项目:

FantasyRPG Project
└── main.tscn
    └── Main Node2D
        ├── World TileMapLayer
        ├── Player CharacterBody2D
        │   ├── Sprite2D
        │   ├── CollisionShape2D
        │   └── player.gd
        ├── Camera2D
        ├── WeatherManager Node
        └── UI CanvasLayer
            ├── HealthBar
            └── InventoryPanel

新手最容易混的几个点

1. Scene 不是只能表示地图

Scene 可以是地图,也可以是玩家、怪物、UI、道具、技能。

你以后要习惯:

能复用的东西都可以做成 Scene

2. Node 不是图片

Sprite2D 是节点,图片是它的 texture 资源。

Sprite2D = 显示图片的节点
Texture2D = 图片资源

3. Resource 不是 Node

Resource 不会出现在 SceneTree 里。

它只是被节点引用的数据。

4. Script 一般挂在 Node 上

Godot 不是先写一堆 JS 模块再渲染页面。

Godot 更常见的是:

创建节点挂脚本节点自己控制自己

5. Signal 不只是按钮点击

Signal 是 Godot 的事件通信方式。

以后你做 RPG,很多系统都可以用信号解耦:

玩家状态变化
天气变化
时间变化
任务变化
背包变化
地图切换
NPC 对话触发

建议你现在记住的最小知识集

先不用背太多,第一部分只要记住这些:

1. Project 是整个游戏工程
2. Main Scene 是游戏启动入口
3. Scene 是可复用的节点树不只是地图
4. Node Godot 的功能单位
5. SceneTree 是游戏运行时真正活着的节点树
6. Resource 是资源和数据不是场景里的对象
7. Script 挂在节点上控制节点行为
8. Signal Godot 的事件通信机制

一个最小完整例子

假设我们要做一个最简单的玩家。

场景结构:

Player CharacterBody2D
├── Sprite2D
└── CollisionShape2D

脚本:

extends CharacterBody2D

@export var speed: float = 120.0

func _physics_process(delta):
    var direction = Vector2.ZERO

    if Input.is_action_pressed("ui_right"):
        direction.x += 1
    if Input.is_action_pressed("ui_left"):
        direction.x -= 1
    if Input.is_action_pressed("ui_down"):
        direction.y += 1
    if Input.is_action_pressed("ui_up"):
        direction.y -= 1

    velocity = direction.normalized() * speed
    move_and_slide()

这里你能看到第一部分所有核心概念:

Player 是一个 Scene
CharacterBody2D 是根 Node
Sprite2D 是子 Node
CollisionShape2D 是子 Node
player.gd Script
speed 是可配置属性
Input 是输入系统
_physics_process 是生命周期方法
move_and_slide 是角色移动方法

总结一句话

Godot 不是先写代码再生成画面,而是先用 Node 搭出 Scene,再用 Script 控制这些 Node,在 SceneTree 里运行起来。

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
godot2026-07-27
Godot 4 常用 UI 节点详解
Godot 4 常用 UI 节点详解 在 Godot 4 中,UI 系统基于 Control(控件) 节点构建。所有 UI 节点都继承自 Control,形成一棵完整的 UI 树。与游戏引擎中常见的"Canvas + DOM"模式不同,Godot 的 UI 系统是声明式的——你在场景中搭好节点树,引擎自动完成布局计算。 一、布局系统:Container 家族 Container 是 Godot UI 的 骨架 。它决定了子节点的大小和位...
学习
godot2026-07-09
Godot 4 自动地形系统(AutoTileSet / Terrains)完全指南
前言 在 2D 游戏开发中,地形瓦片(tile)的拼接是一个绕不开的问题。想象一下:你有一片草地、一条河流、一段平台——如果每一块边缘、角落、过渡区域都要手动选择对应的瓦片图,工作量将是巨大的。 自动地形系统 就是为了解决这个问题而生的。 一、什么是自动地形(Autotiling)? 自动地形的核心思想很简单: 你只管画,引擎帮你选对瓦片 。 当你在 TileMap 上绘制地形时,引擎会自动检测每个瓦片的上下左右邻居,然后根据预设的规则...
学习
godot2026-06-25
Godot 中 zindex 和 ysort 的区别总结
在 Godot 2D 游戏开发中,角色、树木、怪物、地面、技能特效、UI 都需要正确的显示顺序。比如角色走到树前面时,角色应该挡住树;角色走到树后面时,树又应该挡住角色。 这种显示顺序主要和两个概念有关: 和 。 其中 用来手动控制图层顺序, 用来根据物体的 Y 坐标自动排序。 一句话理解 是手动分层。 是根据 Y 坐标自动排序。 简单来说: | 属性 | 作用 | 适合场景 | | | | | | | 数值越大,显示越靠前 | 地面、...
学习
godot2026-06-11
Tileset 资源图的标准和规范
一、什么是 Tileset 资源图 Tileset,中文通常叫“图块资源图”或“瓦片图”,是 2D 游戏中非常常见的一种地图资源组织方式。 简单来说,Tileset 就是把很多小图块按照固定尺寸排列在一张图片里。游戏引擎会按照固定的格子大小去切割这张图片,然后把每个小格子当成一个独立的地图块使用。 比如一个 32×32 像素的 Tileset 中,每一个 tile 都是 32×32 像素。地图编辑器或游戏引擎会按照 32×32 的网格,...
学习
godot2026-05-29
用户角色精灵图制作角色的完整流程
在 2D RPG 游戏里,角色通常不是用一张单独图片完成的,而是用一张“角色精灵图”来做。 所谓角色精灵图,通常是一张包含多个动作帧的大图。比如角色向下走有 4 帧,向左走有 4 帧,向右走有 4 帧,向上走有 4 帧。Godot 会根据这些帧不断切换图片,看起来角色就动起来了。 这篇文章主要介绍:拿到一张角色精灵图之后,如何在 Godot 中把它做成一个可以正常移动、播放动画、和地图产生遮挡关系的角色。 一、先理解角色精灵图是什么 角...
学习
godot2026-05-26
Godot 节点系统详细介绍
Godot 里最核心的东西不是“类”,也不是“组件”,而是 节点 Node 。 你可以把 Godot 的节点理解成: 在前端里,一个页面是由很多 DOM 元素组成的; 在 Godot 里,一个游戏场景是由很多 Node 节点组成的。 比如一个玩家角色,可能不是一个单独对象,而是这样的结构: 这里的 是根节点,下面挂着显示图片、播放动画、碰撞检测、摄像机、音效等子节点。 Godot 官方文档也把节点和场景放在一起讲:多个节点组成树状结构后...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录