第一部分 03:常用 Node 类型总览
这一章解决一个核心问题:
Godot 里面节点那么多,我到底该用哪个?
你不用一开始背所有节点。先记住一个分类:
Node
├── 普通逻辑节点:Node、Timer、AnimationPlayer、AudioStreamPlayer
├── 2D 世界节点:Node2D、Sprite2D、Camera2D、TileMapLayer
├── 2D 物理节点:CharacterBody2D、StaticBody2D、RigidBody2D、Area2D、CollisionShape2D
├── UI 节点:Control、Label、Button、TextureRect、Panel、Container
└── 分层节点:CanvasLayer
Godot 官方文档里说,Node 是所有场景对象的基类,节点可以互相嵌套形成树,一棵节点树就是一个 Scene。也就是说,后面所有节点都可以理解成 Node 的不同“专业版本”。(Godot Engine documentation)
1. Node:最基础的普通节点
它是什么
Node 是最基础的节点。
它没有 2D 位置,没有图像,没有碰撞,没有 UI 尺寸。
它主要适合做:
逻辑管理器
系统节点
数据控制节点
事件中转节点
不需要显示在画面里的对象
比如:
GameManager
WeatherManager
TimeManager
SaveManager
QuestManager
AudioManager
前端类比
Node 有点像一个纯逻辑模块:
class GameManager {
startGame() {}
saveGame() {}
}
或者 Vue / React 里的某个不直接渲染 UI 的 store、service、controller。
常见用法
比如你做一个时间系统:
TimeManager Node
└── time_manager.gd
脚本:
extends Node
signal day_changed(day: int)
var current_day: int = 1
var current_hour: int = 6
func next_day():
current_day += 1
current_hour = 6
day_changed.emit(current_day)
这里 TimeManager 不需要位置,也不需要显示,所以用 Node 就够了。
什么时候用 Node
适合:
不需要出现在 2D 世界里
不需要坐标
不需要碰撞
不需要 UI 布局
只是管理逻辑
比如你的 RPG 项目:
WeatherManager 用 Node
TimeManager 用 Node
InventoryManager 用 Node
DialogueManager 用 Node
SaveManager 用 Node
2. Node2D:2D 世界对象的基础节点
它是什么
Node2D 是所有 2D 世界对象的基础节点。
它比 Node 多了 2D 变换能力:
position
global_position
rotation
rotation_degrees
scale
z_index
visible
官方文档说明,Node2D 是所有 2D 相关节点继承的基础类,拥有 position、rotation、scale 等 2D transform,并且能控制渲染顺序。(Godot Engine documentation)
前端类比
Node2D 类似一个带坐标和 transform 的元素:
position: absolute;
left: 100px;
top: 200px;
transform: rotate(45deg) scale(2);
z-index: 10;
但是 Godot 的坐标不是 CSS 布局,而是游戏世界坐标。
常用属性
position
相对父节点的位置。
position = Vector2(100, 200)
如果父节点是 World,那么这个节点的位置就是相对于 World 的。
global_position
世界坐标。
global_position = Vector2(300, 400)
简单记:
position:相对父节点
global_position:相对整个世界
rotation / rotation_degrees
旋转。
rotation = 1.57
这是弧度。
更好理解的是:
rotation_degrees = 90
scale
缩放。
scale = Vector2(2, 2)
表示放大两倍。
z_index
2D 显示层级。
z_index = 10
值越大,通常越靠前。
常用方法
look_at
让节点朝向某个点。
look_at(target.global_position)
适合:
箭头指向目标
炮塔瞄准玩家
怪物朝向玩家
rotate
旋转一定角度。
rotate(0.1)
to_global
把本地坐标转成世界坐标。
var world_pos = to_global(Vector2(10, 0))
to_local
把世界坐标转成本地坐标。
var local_pos = to_local(player.global_position)
什么时候用 Node2D
适合做 2D 世界里的容器或对象:
World
Objects
Enemies
NPCs
SpawnPoint
Marker
WeatherRoot
EffectRoot
比如:
World Node2D
├── Ground TileMapLayer
├── Objects Node2D
├── NPCs Node2D
├── Enemies Node2D
└── Effects Node2D
3. Sprite2D:显示图片的节点
它是什么
Sprite2D 是用来显示 2D 图片的节点。
官方文档说,Sprite2D 是一个通用精灵节点,用于显示 2D texture,也可以显示图集中的某个区域,或者 sprite sheet 里的某一帧。(Godot Engine documentation)
前端类比
类似:
<img src="/player.png" />
但是 Sprite2D 在 Godot 里是一个节点,有位置、旋转、缩放、层级。
常用属性
texture
要显示的图片资源。
$Sprite2D.texture = preload("res://assets/player.png")
flip_h
水平翻转。
$Sprite2D.flip_h = true
常用于角色左右朝向。
比如:
if direction.x < 0:
$Sprite2D.flip_h = true
elif direction.x > 0:
$Sprite2D.flip_h = false
flip_v
垂直翻转。
$Sprite2D.flip_v = true
用得少一些。
centered
是否以图片中心作为节点原点。
$Sprite2D.centered = true
默认通常是居中。
如果你做像素风,有时图片半像素偏移会导致模糊,这个属性可能会影响观感。官方文档也提醒,像素风图片在居中时可能因为位置落在像素之间而出现变形,可以考虑关闭 centered 或启用 2D 像素吸附设置。(Godot Engine documentation)
hframes / vframes / frame
用于从一张 sprite sheet 中显示某一帧。
比如一张图有 4 列 2 行:
$Sprite2D.hframes = 4
$Sprite2D.vframes = 2
$Sprite2D.frame = 0
然后切换帧:
$Sprite2D.frame = 1
什么时候用 Sprite2D
适合:
玩家图片
NPC 图片
道具图片
装饰物
树木
石头
特效的一张图
不过如果你要做连续动画,后面更常用:
AnimatedSprite2D
AnimationPlayer
4. CharacterBody2D:角色移动节点
它是什么
CharacterBody2D 是 2D 角色物理移动最常用的节点。
你做玩家、NPC、怪物,很多时候都会用它。
官方文档说明,CharacterBody2D 是专门用于由脚本控制移动的 2D 物理体,不会被物理自动推动,但会影响路径上的其他物理体,并提供 move_and_slide() 等高级移动接口。(Godot Engine documentation)
前端类比
这个不太像前端里的某个东西。
你可以粗暴理解成:
带碰撞能力的可移动角色容器
它不是图片,图片通常放在它下面:
Player CharacterBody2D
├── Sprite2D
└── CollisionShape2D
常用属性
velocity
移动速度向量。
velocity = Vector2(100, 0)
表示每秒向右移动 100 像素。
常见写法:
velocity = direction * speed
move_and_slide()
motion_mode
运动模式。
2D RPG 俯视角通常不用太纠结。
平台跳跃游戏会更关心地面、斜坡、重力等配置。
常用方法
move_and_slide
角色移动最常用方法。
move_and_slide()
完整例子:
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()
注意:在 Godot 4 里,move_and_slide() 会使用当前节点的 velocity 属性。
什么时候用 CharacterBody2D
适合:
玩家
可以移动的 NPC
怪物
需要脚本控制移动并发生碰撞的对象
比如:
Player CharacterBody2D
Enemy CharacterBody2D
Villager CharacterBody2D
常见坑
坑 1:CharacterBody2D 自己不会显示图片
你必须加 Sprite2D 或 AnimatedSprite2D。
Player CharacterBody2D
├── Sprite2D
└── CollisionShape2D
坑 2:没有 CollisionShape2D 就没有碰撞形状
CharacterBody2D 是物理体,但需要子节点提供碰撞形状。
Player CharacterBody2D
└── CollisionShape2D
坑 3:角色移动一般放在 _physics_process
不要优先放 _process。
func _physics_process(delta):
velocity = direction * speed
move_and_slide()
5. CollisionShape2D:碰撞形状节点
它是什么
CollisionShape2D 本身不是碰撞物体,它是给父级物理节点提供“碰撞形状”的。
官方文档说,CollisionShape2D 为 CollisionObject2D 父节点提供 Shape2D,可以给 Area2D 检测范围,也可以让 PhysicsBody2D 变成实体碰撞对象。(Godot Engine documentation)
它通常不能单独用
错误理解:
CollisionShape2D = 一个碰撞物体
正确理解:
CollisionShape2D = 碰撞形状
父节点才是碰撞对象
比如:
Player CharacterBody2D
└── CollisionShape2D
这里真正参与物理的是 Player CharacterBody2D,CollisionShape2D 只是告诉它碰撞范围多大。
常用属性
shape
碰撞形状资源。
常见形状:
RectangleShape2D
CircleShape2D
CapsuleShape2D
SegmentShape2D
WorldBoundaryShape2D
角色常用:
CapsuleShape2D
RectangleShape2D
宝箱、墙、门常用:
RectangleShape2D
disabled
是否禁用碰撞。
$CollisionShape2D.disabled = true
不过官方文档提示,修改 disabled 这类碰撞属性时应该用 set_deferred()。(Godot Engine documentation)
更稳的写法:
$CollisionShape2D.set_deferred("disabled", true)
什么时候用 CollisionShape2D
只要你需要碰撞或检测,基本都要它:
玩家碰撞
怪物碰撞
墙体碰撞
宝箱交互范围
NPC 对话范围
攻击判定范围
进入房间触发区域
6. Area2D:区域检测节点
它是什么
Area2D 是用来检测“有东西进入/离开某个区域”的节点。
官方文档说明,Area2D 是一个 2D 空间区域,由一个或多个 CollisionShape2D 或 CollisionPolygon2D 子节点定义,可以检测其他 CollisionObject2D 进入或离开。(Godot Engine documentation)
前端类比
有点像一个 invisible hitbox:
看不见的触发区域
或者网页里的鼠标 hover 区域、点击热区,只不过 Godot 里它检测的是物理对象。
常见结构
NPC 对话范围
NPC CharacterBody2D
├── Sprite2D
├── CollisionShape2D
└── TalkArea Area2D
└── CollisionShape2D
玩家进入 TalkArea,就显示“按 E 对话”。
宝箱交互范围
Chest StaticBody2D
├── Sprite2D
├── CollisionShape2D
└── InteractArea Area2D
└── CollisionShape2D
玩家进入宝箱范围,可以按 E 打开。
地图传送门
Door Area2D
└── CollisionShape2D
玩家进入后切换场景。
常用信号
body_entered
有物理 body 进入区域。
func _on_body_entered(body):
print(body.name, "进入区域")
body_exited
有物理 body 离开区域。
func _on_body_exited(body):
print(body.name, "离开区域")
area_entered
有另一个 Area2D 进入。
func _on_area_entered(area):
print(area.name)
代码例子:玩家进入对话区域
extends Area2D
var player_inside: bool = false
func _ready():
body_entered.connect(_on_body_entered)
body_exited.connect(_on_body_exited)
func _on_body_entered(body):
if body.name == "Player":
player_inside = true
print("可以对话")
func _on_body_exited(body):
if body.name == "Player":
player_inside = false
print("离开对话范围")
Area2D 和 CharacterBody2D 的区别
| 节点 | 主要作用 | 典型用途 |
|---|---|---|
| CharacterBody2D | 可移动、有碰撞的角色 | 玩家、怪物、NPC |
| Area2D | 检测进入/离开区域 | 对话范围、攻击范围、传送点 |
一句话:
CharacterBody2D 是“身体”
Area2D 是“感应区域”
7. StaticBody2D:静态物体节点
它是什么
StaticBody2D 用于不主动移动的物理物体。
适合:
墙
石头
树
房子
桌子
地形障碍
不可推动的箱子
典型结构:
Wall StaticBody2D
└── CollisionShape2D
或者:
Tree StaticBody2D
├── Sprite2D
└── CollisionShape2D
什么时候用 StaticBody2D
只要这个对象:
有碰撞
不需要自己移动
不需要被物理推来推去
就可以用它。
比如 RPG 地图里的树、石头、围栏、墙壁。
8. RigidBody2D:受物理影响的物体
它是什么
RigidBody2D 是会被物理系统影响的物体。
适合:
被撞开的箱子
会滚动的石头
会掉落的物体
弹来弹去的球
它通常由物理引擎控制,而不是你每帧手动设置位置。
和 CharacterBody2D 的区别
| 节点 | 谁控制移动 | 适合 |
|---|---|---|
| CharacterBody2D | 你写脚本控制 | 玩家、怪物、NPC |
| RigidBody2D | 物理引擎控制 | 球、箱子、掉落物、被撞飞物体 |
做 RPG 初期,你可以先少用 RigidBody2D。
角色移动优先用:
CharacterBody2D
地图障碍优先用:
StaticBody2D
9. Camera2D:2D 摄像机
它是什么
Camera2D 控制玩家看到哪一块游戏世界。
官方文档说,Camera2D 是 2D 场景的相机节点,会让屏幕跟随这个节点滚动,用它做可滚动场景比手动移动 CanvasItem 节点更方便。并且每个 Viewport 同时只有一个活动相机。(Godot Engine documentation)
前端类比
有点像浏览器 viewport,但游戏里是你控制 viewport 看世界的哪一块。
游戏世界很大
屏幕只能看到一小块
Camera2D 决定当前看到哪里
常见用法
放在 Player 下面
Player CharacterBody2D
├── Sprite2D
├── CollisionShape2D
└── Camera2D
这样相机会跟着玩家走。
放在 Main 下面,用脚本跟随玩家
Main Node2D
├── World
├── Player
└── Camera2D
脚本:
extends Camera2D
@export var target: Node2D
func _process(delta):
if target:
global_position = target.global_position
常用属性
enabled
是否启用这个相机。
$Camera2D.enabled = true
zoom
缩放视野。
$Camera2D.zoom = Vector2(2, 2)
注意:在 Godot 里 zoom 越大,看起来越近;Vector2(0.5, 0.5) 看起来更远。
position_smoothing_enabled
是否开启平滑跟随。
$Camera2D.position_smoothing_enabled = true
position_smoothing_speed
平滑速度。
$Camera2D.position_smoothing_speed = 5.0
RPG 常见配置
玩家场景:
Player CharacterBody2D
├── Sprite2D
├── CollisionShape2D
└── Camera2D
Camera2D 属性:
Enabled: true
Position Smoothing Enabled: true
Position Smoothing Speed: 5
Zoom: Vector2(2, 2) 或 Vector2(3, 3)
像素风/TileMap 游戏一般会把视角放大一点,看起来更清楚。
10. Control:UI 节点的基础类
它是什么
Control 是 Godot UI 系统的基础节点。
所有常见 UI 基本都继承自它:
Label
Button
TextureRect
Panel
Container
LineEdit
ProgressBar
RichTextLabel
官方文档说,Control 是所有 GUI 控件的基类,会根据父控件调整自身位置和尺寸;它有 bounding rectangle、anchor、offset 等布局概念。(Godot Engine documentation)
前端类比
Control 非常像 HTML/CSS UI 元素。
它关心:
尺寸
锚点
边距
布局
鼠标输入
焦点
UI 事件
跟 Node2D 不一样,Control 更像界面层。
Control 和 Node2D 的区别
| 类型 | 用途 | 坐标系统 | 常见子类 |
|---|---|---|---|
| Node2D | 游戏世界对象 | 世界坐标 | Sprite2D、CharacterBody2D、Camera2D |
| Control | UI 界面 | UI 布局坐标 | Button、Label、Panel、TextureRect |
简单记:
游戏世界用 Node2D
界面 UI 用 Control
常用属性
position
UI 元素位置。
$Label.position = Vector2(20, 20)
size
UI 元素大小。
$Panel.size = Vector2(300, 200)
anchors
锚点。
用于适配屏幕尺寸。
比如:
左上角
居中
铺满父容器
右下角
visible
显示隐藏。
$InventoryPanel.visible = false
UI 常见结构
UI CanvasLayer
└── HUD Control
├── HealthLabel Label
├── CoinLabel Label
├── InventoryButton Button
└── DialogPanel Panel
11. CanvasLayer:UI 和世界分层
它是什么
CanvasLayer 用来让一组 2D/Control 节点独立渲染在某个层级。
官方文档说明,CanvasLayer 的 layer 是数字索引,默认 2D 场景在 index 0,layer = 1 会画在上面,layer = -1 会画在下面;它很适合做 HUD 血条这类覆盖层。(Godot Engine documentation)
为什么 UI 通常放 CanvasLayer
如果 UI 直接放在 World 下面:
World Node2D
├── Player
├── TileMapLayer
└── HealthBar
当 Camera2D 移动时,UI 可能跟着世界一起移动。
这通常不是你想要的。
所以 UI 一般这样放:
Main Node2D
├── World Node2D
├── Player
├── Camera2D
└── UI CanvasLayer
└── HUD Control
├── HealthBar
└── CoinLabel
这样 UI 会固定在屏幕上。
前端类比
CanvasLayer 有点像:
position: fixed;
z-index: 999;
HUD、血条、背包按钮、对话框都可以放里面。
常用属性
layer
渲染层级。
$UI.layer = 1
建议:
背景层:-1
游戏世界:0
普通 UI:1
弹窗/菜单:2
调试浮层:10
12. TileMapLayer:瓦片地图节点
它是什么
TileMapLayer 是 Godot 4 里用于 2D 瓦片地图的节点。
官方文档说明,TileMapLayer 使用 TileSet 创建基于网格的地图;和已经 deprecated 的 TileMap 不同,TileMapLayer 只有一层 tiles,如果需要多层地图,可以使用多个 TileMapLayer。(Godot Engine documentation)
前端类比
有点像一个二维数组渲染器:
const map = [
[grass, grass, road],
[grass, tree, road],
[water, grass, road],
]
然后按照格子画出来。
常见结构
World Node2D
├── GroundLayer TileMapLayer
├── DecorationLayer TileMapLayer
├── ObjectLayer TileMapLayer
└── CollisionLayer TileMapLayer
或者简单一点:
World Node2D
└── Ground TileMapLayer
常用属性
tile_set
瓦片集资源。
TileMapLayer 使用 TileSet
TileSet 里面包含草地、道路、水、墙等 tile
collision_enabled
是否启用 TileSet 里的碰撞。
collision_enabled = true
如果你的 TileSet 里给墙、树、石头配置了碰撞,TileMapLayer 需要启用碰撞才会生效。
什么时候用 TileMapLayer
适合:
草地
道路
水面
墙
地板
屋内地面
地图装饰
大面积规则地图
不太适合:
玩家
NPC
怪物
复杂交互物
这些更适合独立 Scene。
13. Timer:计时器节点
它是什么
Timer 是倒计时节点。
官方文档说,Timer 是处理时间逻辑最简单的方式,当计时达到 wait_time 后会发出 timeout 信号。它进入 SceneTree 后可以手动 start(),也可以通过 autostart 自动开始。(Godot Engine documentation)
前端类比
类似:
setTimeout(() => {}, 1000)
setInterval(() => {}, 1000)
但 Godot 里它是节点,可以在编辑器配置,也可以连接信号。
常用属性
wait_time
等待时间,单位秒。
$Timer.wait_time = 1.5
one_shot
是否只触发一次。
$Timer.one_shot = true
如果是 false,就会循环触发,有点像 setInterval。
autostart
进入场景树后是否自动开始。
$Timer.autostart = true
常用方法
start
开始计时。
$Timer.start()
也可以指定时间:
$Timer.start(2.0)
stop
停止计时。
$Timer.stop()
常用信号
timeout
计时结束时触发。
func _ready():
$Timer.timeout.connect(_on_timer_timeout)
func _on_timer_timeout():
print("时间到了")
适合用在哪里
怪物每 2 秒攻击一次
天气每隔一段时间变化
NPC 每隔几秒换一句话
技能冷却
对话文字逐字显示
临时提示 3 秒后隐藏
14. AnimationPlayer:动画播放器
它是什么
AnimationPlayer 用来播放动画。
官方文档说,AnimationPlayer 是通用动画播放节点,适合更复杂的动画,比如具有非简单时间安排的动画;相比 Tween,如果使用动画轨道编辑器更方便,可以使用 AnimationPlayer。(Godot Engine documentation)
它能动画什么
不只是角色图片。
它可以动画很多属性:
position
rotation
scale
modulate
visible
Sprite2D.frame
Color
音量
自定义属性
甚至调用方法
比如:
宝箱打开动画
门打开动画
UI 弹出动画
角色待机动画
攻击动画
天气渐变
灯光变化
常用方法
play
播放动画。
$AnimationPlayer.play("open")
stop
停止动画。
$AnimationPlayer.stop()
is_playing
是否正在播放。
if $AnimationPlayer.is_playing():
print("动画播放中")
常用信号
animation_finished
动画播放结束。
func _ready():
$AnimationPlayer.animation_finished.connect(_on_animation_finished)
func _on_animation_finished(anim_name):
print("动画结束:", anim_name)
适合用在哪里
宝箱打开
门开关
角色攻击
UI 面板弹出
淡入淡出
技能特效
地图环境变化
15. Label:文本节点
它是什么
Label 是显示文字的 UI 节点。
常用于:
血量文字
金币数量
任务提示
NPC 名字
调试信息
结构:
HUD Control
└── CoinLabel Label
代码:
$CoinLabel.text = "金币:100"
常用属性
text
显示文本。
$Label.text = "Hello Godot"
horizontal_alignment
水平对齐。
左对齐
居中
右对齐
vertical_alignment
垂直对齐。
RPG 例子
func update_gold(value: int):
$UI/HUD/GoldLabel.text = "金币:" + str(value)
16. Button:按钮节点
它是什么
Button 是按钮 UI 节点。
常用于:
开始游戏
继续游戏
打开背包
确认
取消
菜单按钮
常用信号
pressed
按钮点击。
func _ready():
$Button.pressed.connect(_on_button_pressed)
func _on_button_pressed():
print("按钮被点击")
这和前端非常像:
<button onClick={handleClick}>开始游戏</button>
常用属性
text
按钮文字。
$Button.text = "开始游戏"
disabled
是否禁用。
$Button.disabled = true
17. TextureRect:UI 图片节点
它是什么
TextureRect 是 UI 里的图片显示节点。
它和 Sprite2D 都能显示图片,但用途不同:
| 节点 | 用途 |
|---|---|
| Sprite2D | 游戏世界里的图片 |
| TextureRect | UI 界面里的图片 |
比如:
头像
背包格子背景
按钮贴图
对话框背景
技能图标
建议:
地图里的树:Sprite2D
UI 里的头像:TextureRect
18. Panel / ColorRect:UI 背景节点
Panel
适合做 UI 面板背景。
DialogPanel Panel
InventoryPanel Panel
MenuPanel Panel
ColorRect
显示一块纯色矩形。
适合:
遮罩
淡入淡出
调试背景
血条底色
比如黑屏淡出:
FadeLayer CanvasLayer
└── FadeRect ColorRect
19. Container:UI 自动布局节点
它是什么
Container 是 UI 布局容器。
类似前端里的 flex/grid 布局思想。
常见:
VBoxContainer
HBoxContainer
GridContainer
MarginContainer
CenterContainer
前端类比
display: flex;
flex-direction: column;
gap: 8px;
类似:
VBoxContainer
横向排列:
HBoxContainer
网格排列:
GridContainer
背包 UI 例子
InventoryPanel Panel
└── GridContainer
├── Slot1
├── Slot2
├── Slot3
└── Slot4
以后做背包、技能栏、菜单,Container 很重要。
20. 常见节点选择速查表
我想显示一张游戏里的图片
用:
Sprite2D
我想显示 UI 图片
用:
TextureRect
我想让玩家能移动和碰撞
用:
CharacterBody2D
├── Sprite2D
└── CollisionShape2D
我想做墙、树、石头等障碍
用:
StaticBody2D
├── Sprite2D
└── CollisionShape2D
或者在 TileMapLayer 的 TileSet 里配置碰撞。
我想检测玩家靠近 NPC
用:
Area2D
└── CollisionShape2D
我想做地图
用:
TileMapLayer
我想做 UI
用:
CanvasLayer
└── Control
├── Label
├── Button
└── Panel
我想让屏幕跟随玩家
用:
Camera2D
我想每隔几秒执行一次
用:
Timer
我想播放动画
用:
AnimationPlayer
21. 一个 RPG 初始场景推荐结构
你现在做 2D RPG,可以先这样搭:
Main Node2D
├── World Node2D
│ ├── Ground TileMapLayer
│ ├── Decorations TileMapLayer
│ ├── Objects Node2D
│ ├── NPCs Node2D
│ └── Enemies Node2D
├── Player CharacterBody2D
│ ├── Sprite2D
│ ├── CollisionShape2D
│ └── Camera2D
├── Systems Node
│ ├── TimeManager Node
│ ├── WeatherManager Node
│ └── AudioManager Node
└── UI CanvasLayer
└── HUD Control
├── HealthLabel Label
├── CoinLabel Label
└── InventoryButton Button
这个结构已经很够你做第一版了。
22. 一个玩家场景推荐结构
Player CharacterBody2D
├── BodySprite Sprite2D
├── CollisionShape2D
├── InteractArea Area2D
│ └── CollisionShape2D
├── AnimationPlayer
└── Camera2D
说明:
CharacterBody2D:负责玩家移动和碰撞
BodySprite:负责显示玩家图片
CollisionShape2D:负责玩家身体碰撞
InteractArea:负责检测可交互对象
AnimationPlayer:负责动画
Camera2D:负责镜头跟随
23. 一个 NPC 场景推荐结构
NPC CharacterBody2D
├── BodySprite Sprite2D
├── CollisionShape2D
├── TalkArea Area2D
│ └── CollisionShape2D
└── AnimationPlayer
说明:
CharacterBody2D:NPC 可以移动或阻挡玩家
BodySprite:显示 NPC
CollisionShape2D:NPC 身体碰撞
TalkArea:玩家靠近后可以对话
AnimationPlayer:待机、走路、说话动画
24. 一个宝箱场景推荐结构
Chest StaticBody2D
├── Sprite2D
├── CollisionShape2D
├── InteractArea Area2D
│ └── CollisionShape2D
└── AnimationPlayer
说明:
StaticBody2D:宝箱是静态障碍
Sprite2D:显示宝箱图片
CollisionShape2D:挡住玩家
InteractArea:检测玩家是否靠近
AnimationPlayer:打开动画
25. 一个 UI 场景推荐结构
HUD CanvasLayer
└── Root Control
├── TopBar HBoxContainer
│ ├── HealthLabel Label
│ └── GoldLabel Label
├── DialogPanel Panel
│ └── DialogText Label
└── BottomBar HBoxContainer
├── InventoryButton Button
└── MenuButton Button
注意:
CanvasLayer 负责固定在屏幕上
Control 负责 UI 根布局
Container 负责排列
Label/Button 负责具体显示和交互
26. 新手最容易选错的节点
1. 用 Sprite2D 做 UI 图片
不推荐。
UI 图片应该用:
TextureRect
游戏世界图片才用:
Sprite2D
2. 用 Node2D 做 UI 根节点
不推荐。
UI 根节点建议:
CanvasLayer
└── Control
3. 给 CharacterBody2D 加了 Sprite2D,但没加 CollisionShape2D
这样角色看得见,但碰撞可能不正常。
推荐:
Player CharacterBody2D
├── Sprite2D
└── CollisionShape2D
4. 用 Area2D 当墙
不推荐。
Area2D 是检测区域,不是实体墙。
墙更适合:
StaticBody2D
└── CollisionShape2D
或者 TileSet 碰撞。
5. 所有逻辑都塞 Main 节点
短期方便,后期灾难。
推荐拆:
Player 控制玩家
WeatherManager 控制天气
TimeManager 控制时间
HUD 控制 UI
NPC 控制 NPC 自己
27. 这一章你先记住这些
Node:纯逻辑节点
Node2D:2D 世界对象基础节点
Sprite2D:显示游戏世界图片
CharacterBody2D:脚本控制的可移动角色
CollisionShape2D:碰撞形状
Area2D:区域检测
StaticBody2D:静态障碍物
RigidBody2D:受物理影响的物体
Camera2D:2D 镜头
Control:UI 基础节点
CanvasLayer:UI/画面分层
TileMapLayer:瓦片地图
Timer:计时器
AnimationPlayer:动画播放器
Label:文字
Button:按钮
TextureRect:UI 图片
Container:UI 自动布局
一句更实用的:
游戏世界:Node2D 系
UI 界面:Control 系
角色移动:CharacterBody2D
区域触发:Area2D
地图:TileMapLayer
管理系统:Node如果您觉得这篇文章有帮助,请点个赞吧~
评论
请登录后发表评论
去登录