第一部分 12:项目结构和代码组织

2026-05-19
412114 分钟
...

这一章讲 Godot 项目应该怎么分目录、怎么放场景、脚本、资源、素材和全局系统。

先记一句话:

Godot 不强制你必须怎么分目录但项目越早整理后面越不容易乱

Godot 官方文档也提到,Godot 对项目结构和文件系统使用没有强制限制,所以刚开始学习时可能会不知道怎么组织文件;官方给出的是一种推荐起点,而不是唯一标准。(Godot Engine documentation)

1. 为什么项目结构很重要

如果项目刚开始不整理,你很快会变成这样:

res://
├── player.gd
├── player.png
├── main.tscn
├── enemy.tscn
├── grass.png
├── hud.gd
├── bgm.ogg
├── test.tscn
├── test2.tscn
├── new_scene.tscn
├── slime.png
├── item.gd
├── item2.gd
├── world.tscn
└── 不知道干啥的文件.tres

刚开始能跑,但一旦你有:

玩家
地图
NPC
宝箱
天气
时间
背包
任务
卡牌
存档
UI
音频
特效

根目录就会变成“考古现场”。

更好的方式是从一开始就分清:

scenes放场景
scripts放脚本
assets放原始素材
resources Godot 配置资源
autoload放全局系统

2. 推荐的基础目录结构

对于你的 2D RPG 项目,我建议先这样分:

res://
├── project.godot
├── scenes/
├── scripts/
├── assets/
├── resources/
├── shaders/
├── themes/
└── addons/

每个目录负责一类东西。

scenes/
 .tscn 场景文件

scripts/
 .gd 脚本文件

assets/
放图片音频字体tileset 原图等素材

resources/
 .tres 配置资源比如物品技能敌人属性天气配置

shaders/
 .gdshader 着色器

themes/
 UI Theme字体样式控件样式

addons/
放插件

Godot 的文件系统会把脚本、场景、PNG 图片等都当作资源处理;资源可以引用磁盘上的其他资源,Godot 会记录这些路径关系。(Godot Engine documentation)

3. project.godot 是什么

项目根目录里最重要的文件是:

project.godot

它是 Godot 项目的核心配置文件。

你可以把它类比成前端里的:

package.json
vite.config.ts
项目设置
入口配置

它会记录很多项目级配置,比如:

项目名称
主场景
输入映射
渲染设置
窗口设置
Autoload 配置
导出相关设置

你一般不需要手动改它,大多数配置都通过 Godot 编辑器里的 Project Settings 修改。

4. .godot 目录是什么

Godot 项目里还会出现:

.godot/

这是编辑器自动生成的缓存目录。

官方版本控制文档建议把 .godot/ 加入版本控制忽略列表,因为它保存的是各种项目缓存数据,没必要提交到仓库。(Godot Engine documentation)

所以你的 .gitignore 里应该有:

.godot/

如果你创建项目时勾选了生成版本控制元数据,Godot 默认生成的忽略规则也会自动忽略 .godot/。(Godot Engine documentation)

5. 推荐 .gitignore

Godot 项目可以先用这个:

.godot/
.import/
export.cfg
export_presets.cfg
*.translation

# 操作系统文件
.DS_Store
Thumbs.db

# 编辑器文件
.vscode/
.idea/

# 日志和临时文件
*.log
tmp/
temp/

说明:

.godot/
Godot 编辑器缓存不提交

.DS_Store
macOS 自动生成文件不提交

.vscode/ .idea/
编辑器配置看团队习惯决定是否提交

export_presets.cfg
如果里面有敏感导出配置可以不提交

如果你是个人项目,.vscode/ 也可以提交部分配置,比如格式化、任务配置。团队项目就要更谨慎。

6. scenes 目录:放场景

scenes.tscn 文件。

推荐结构:

res://scenes/
├── main/
├── player/
├── world/
├── npcs/
├── enemies/
├── items/
├── ui/
├── systems/
├── effects/
└── autoload/

具体可以这样:

res://scenes/
├── main/
│   └── main.tscn
├── player/
│   └── player.tscn
├── world/
│   ├── town.tscn
│   ├── forest.tscn
│   ├── house_inside.tscn
│   └── dungeon_01.tscn
├── npcs/
│   ├── villager.tscn
│   └── merchant.tscn
├── enemies/
│   ├── slime.tscn
│   ├── bat.tscn
│   └── wolf.tscn
├── items/
│   ├── chest.tscn
│   ├── dropped_item.tscn
│   └── collectable.tscn
├── ui/
│   ├── hud.tscn
│   ├── inventory_panel.tscn
│   ├── dialog_box.tscn
│   └── pause_menu.tscn
├── systems/
│   ├── weather_manager.tscn
│   └── time_manager.tscn
├── effects/
│   ├── hit_effect.tscn
│   ├── rain_effect.tscn
│   └── snow_effect.tscn
└── autoload/
    ├── audio_manager.tscn
    └── scene_manager.tscn

7. scenes 目录的核心原则

一个简单规则:

能在游戏里作为对象出现的东西通常可以做成 scene

比如:

玩家
敌人
NPC
宝箱

掉落物
UI 面板
技能特效
天气效果
地图
房间

它们都适合放在 scenes/

比如玩家场景:

res://scenes/player/player.tscn

怪物场景:

res://scenes/enemies/slime.tscn

UI 场景:

res://scenes/ui/hud.tscn

8. scripts 目录:放脚本

scripts.gd 逻辑代码。

推荐结构:

res://scripts/
├── player/
├── world/
├── npcs/
├── enemies/
├── items/
├── ui/
├── systems/
├── autoload/
├── resources/
└── utils/

具体:

res://scripts/
├── player/
│   └── player.gd
├── world/
│   ├── world.gd
│   └── door.gd
├── npcs/
│   └── npc.gd
├── enemies/
│   ├── enemy.gd
│   └── slime.gd
├── items/
│   ├── chest.gd
│   ├── dropped_item.gd
│   └── collectable.gd
├── ui/
│   ├── hud.gd
│   ├── inventory_panel.gd
│   ├── dialog_box.gd
│   └── pause_menu.gd
├── systems/
│   ├── weather_manager.gd
│   ├── time_manager.gd
│   └── interaction_system.gd
├── autoload/
│   ├── game.gd
│   ├── scene_manager.gd
│   ├── audio_manager.gd
│   ├── save_manager.gd
│   └── item_database.gd
├── resources/
│   ├── item_data.gd
│   ├── skill_data.gd
│   ├── enemy_stats.gd
│   ├── weather_data.gd
│   └── dialogue_data.gd
└── utils/
    ├── groups.gd
    └── constants.gd

9. 脚本和场景要不要放一起

Godot 项目常见有两种风格。

风格一:场景和脚本分开放

scenes/player/player.tscn
scripts/player/player.gd

优点:

目录职责清楚
脚本集中管理
适合大项目

缺点:

场景和脚本不在一起跳转时要多找一下

风格二:场景和脚本放一起

player/
├── player.tscn
└── player.gd

优点:

一个模块的东西都在一起
很好找
适合组件化开发

缺点:

资源多了后每个目录可能比较杂

10. 我建议你用哪种

对于你现在这种从 0 开始做 RPG,我建议用折中方式:

scenes .tscn
scripts .gd
assets 放素材
resources 放配置

也就是:

res://scenes/player/player.tscn
res://scripts/player/player.gd

原因是你现在还在学习阶段,这种结构最清楚。

后面如果项目大了,也可以改成“功能模块聚合”:

modules/player/
├── player.tscn
├── player.gd
├── player_sprite.png
└── player_stats.tres

但入门阶段先不要太工程化,别一上来就把文件夹分成洋葱,剥到最后自己先哭了。

11. assets 目录:放原始素材

assets 放图片、音频、字体、tileset 原图等。

推荐结构:

res://assets/
├── sprites/
├── tilesets/
├── ui/
├── audio/
├── fonts/
├── portraits/
└── icons/

具体:

res://assets/
├── sprites/
│   ├── player/
│   │   └── player.png
│   ├── enemies/
│   │   ├── slime.png
│   │   └── bat.png
│   ├── npcs/
│   │   └── villager.png
│   └── objects/
│       ├── chest.png
│       └── door.png
├── tilesets/
│   ├── forest_tiles.png
│   ├── house_tiles.png
│   └── dungeon_tiles.png
├── ui/
│   ├── panels/
│   ├── buttons/
│   └── cursors/
├── audio/
│   ├── bgm/
│   │   └── town_theme.ogg
│   ├── sfx/
│   │   ├── click.ogg
│   │   └── open_chest.ogg
│   └── ambience/
│       ├── rain.ogg
│       └── forest.ogg
├── fonts/
│   └── main_font.ttf
├── portraits/
│   └── villager.png
└── icons/
    ├── potion.png
    ├── sword.png
    └── card_fireball.png

12. assets 和 resources 的区别

这个很容易混。

assets
原始素材比如图片音频字体

resources
Godot 里的配置资源比如 ItemDataSkillDataWeatherData

举例:

assets/icons/potion.png
这是药水图标图片

resources/items/potion.tres
这是药水的物品配置

potion.tres 里面可以引用 potion.png

比如:

class_name ItemData
extends Resource

@export var id: String
@export var display_name: String
@export var icon: Texture2D
@export var price: int

icon 字段拖入:

res://assets/icons/potion.png

13. resources 目录:放配置资源

resources.tres 这类 Godot 配置资源。

推荐:

res://resources/
├── items/
├── skills/
├── enemies/
├── weather/
├── dialogues/
├── quests/
├── cards/
└── themes/

具体:

res://resources/
├── items/
│   ├── potion.tres
│   ├── herb.tres
│   └── iron_sword.tres
├── skills/
│   ├── fireball.tres
│   ├── heal.tres
│   └── slash.tres
├── enemies/
│   ├── slime_stats.tres
│   ├── bat_stats.tres
│   └── wolf_stats.tres
├── weather/
│   ├── sunny.tres
│   ├── rainy.tres
│   ├── snowy.tres
│   └── foggy.tres
├── dialogues/
│   ├── villager_intro.tres
│   └── merchant_intro.tres
├── quests/
│   ├── find_sword.tres
│   └── village_intro.tres
└── cards/
    ├── slash.tres
    ├── guard.tres
    └── fireball.tres

官方资源文档里也强调,Resource 是数据容器,自己不做事情,而是被节点使用;这正好适合存放物品、技能、天气、任务这类配置数据。(Godot Engine documentation)

14. shaders 目录:放 Shader

如果你后面做:

雾气
水面波纹
雨天屏幕效果
雪地闪光
角色受伤闪白
UI 发光

可以建:

res://shaders/
├── fog.gdshader
├── water.gdshader
├── damage_flash.gdshader
├── outline.gdshader
└── rain_overlay.gdshader

如果 Shader 只属于某个特定场景,也可以放到对应模块下。

但入门阶段统一放 shaders/ 很清楚。

15. themes 目录:放 UI 主题

Godot UI 后面会用到 Theme。

你可以放:

res://themes/
├── default_theme.tres
├── rpg_theme.tres
└── fonts/

UI 相关资源也可以统一放:

res://assets/ui/

但 Theme 这种 Godot Resource,我更建议放 themes/resources/themes/

16. addons 目录:放插件

Godot 插件通常放:

res://addons/

比如:

res://addons/dialogue_manager/
res://addons/terrain_plugin/

这个目录一般由插件自己管理,不要乱改里面文件,除非你知道自己在干啥。

17. 推荐你的完整 RPG 目录结构

你现在的 RPG 项目可以按这个来:

res://
├── project.godot
├── scenes/
│   ├── main/
│   │   └── main.tscn
│   ├── player/
│   │   └── player.tscn
│   ├── world/
│   │   ├── town.tscn
│   │   ├── forest.tscn
│   │   └── house_inside.tscn
│   ├── npcs/
│   │   ├── villager.tscn
│   │   └── merchant.tscn
│   ├── enemies/
│   │   ├── slime.tscn
│   │   └── bat.tscn
│   ├── items/
│   │   ├── chest.tscn
│   │   └── dropped_item.tscn
│   ├── ui/
│   │   ├── hud.tscn
│   │   ├── inventory_panel.tscn
│   │   ├── dialog_box.tscn
│   │   └── pause_menu.tscn
│   ├── effects/
│   │   ├── hit_effect.tscn
│   │   ├── rain_effect.tscn
│   │   └── snow_effect.tscn
│   └── autoload/
│       ├── audio_manager.tscn
│       └── scene_manager.tscn
├── scripts/
│   ├── player/
│   │   └── player.gd
│   ├── world/
│   │   ├── world.gd
│   │   └── door.gd
│   ├── npcs/
│   │   └── npc.gd
│   ├── enemies/
│   │   └── enemy.gd
│   ├── items/
│   │   ├── chest.gd
│   │   └── dropped_item.gd
│   ├── ui/
│   │   ├── hud.gd
│   │   ├── inventory_panel.gd
│   │   └── dialog_box.gd
│   ├── systems/
│   │   ├── weather_manager.gd
│   │   ├── time_manager.gd
│   │   └── interaction_system.gd
│   ├── autoload/
│   │   ├── game.gd
│   │   ├── save_manager.gd
│   │   ├── item_database.gd
│   │   └── quest_manager.gd
│   ├── resources/
│   │   ├── item_data.gd
│   │   ├── skill_data.gd
│   │   ├── enemy_stats.gd
│   │   ├── weather_data.gd
│   │   ├── dialogue_data.gd
│   │   └── card_data.gd
│   └── utils/
│       ├── groups.gd
│       └── constants.gd
├── assets/
│   ├── sprites/
│   ├── tilesets/
│   ├── ui/
│   ├── audio/
│   ├── fonts/
│   ├── portraits/
│   └── icons/
├── resources/
│   ├── items/
│   ├── skills/
│   ├── enemies/
│   ├── weather/
│   ├── dialogues/
│   ├── quests/
│   └── cards/
├── shaders/
├── themes/
└── addons/

18. main.tscn 应该放什么

主场景建议放:

Main Node2D
├── World Node2D
├── Player
├── Systems Node
└── UI CanvasLayer

更完整:

Main Node2D
├── World Node2D
│   ├── Ground TileMapLayer
│   ├── Decoration TileMapLayer
│   ├── Objects Node2D
│   ├── NPCs Node2D
│   └── Enemies Node2D
├── Player
├── Systems Node
│   ├── WeatherManager
│   └── TimeManager
└── UI CanvasLayer
    ├── HUD
    ├── DialogBox
    └── InventoryPanel

Main 的职责是:

组合当前场景
连接 PlayerHUDWorldSystems
处理当前地图内的对象关系

不要让 Main 变成:

所有游戏逻辑都写在 Main.gd

Main 应该像一个“组装层”,不是“上帝脚本”。

19. player 目录怎么放

res://scenes/player/
└── player.tscn

res://scripts/player/
└── player.gd

res://assets/sprites/player/
├── player_idle.png
├── player_walk.png
└── player_attack.png

如果后面玩家复杂了,可以继续拆:

res://scripts/player/
├── player.gd
├── player_movement.gd
├── player_interaction.gd
└── player_combat.gd

但初期不要拆太细。

一个 player.gd 先够用。

20. enemy 目录怎么放

res://scenes/enemies/
├── slime.tscn
├── bat.tscn
└── wolf.tscn

res://scripts/enemies/
├── enemy.gd
├── slime.gd
└── bat.gd

res://resources/enemies/
├── slime_stats.tres
├── bat_stats.tres
└── wolf_stats.tres

res://assets/sprites/enemies/
├── slime.png
├── bat.png
└── wolf.png

推荐逻辑:

enemy.gd
通用敌人逻辑比如血量受伤死亡追踪

slime.gd
史莱姆特有逻辑

slime_stats.tres
史莱姆数据比如血量速度伤害掉落

21. item 目录怎么放

res://scenes/items/
├── chest.tscn
├── dropped_item.tscn
└── collectable.tscn

res://scripts/items/
├── chest.gd
├── dropped_item.gd
└── collectable.gd

res://resources/items/
├── potion.tres
├── herb.tres
└── iron_sword.tres

res://assets/icons/
├── potion.png
├── herb.png
└── iron_sword.png

区分:

chest.tscn
是宝箱这个场景对象

potion.tres
是药水这份物品数据

potion.png
是药水图标素材

22. ui 目录怎么放

res://scenes/ui/
├── hud.tscn
├── dialog_box.tscn
├── inventory_panel.tscn
├── pause_menu.tscn
└── card_view.tscn

res://scripts/ui/
├── hud.gd
├── dialog_box.gd
├── inventory_panel.gd
├── pause_menu.gd
└── card_view.gd

res://assets/ui/
├── panels/
├── buttons/
├── slots/
└── cursors/

UI 相关要注意:

游戏世界图片用 Sprite2D
UI 图片用 TextureRect
UI 根节点通常是 Control CanvasLayer

23. world 目录怎么放

res://scenes/world/
├── town.tscn
├── forest.tscn
├── house_inside.tscn
└── dungeon_01.tscn

res://scripts/world/
├── world.gd
├── door.gd
├── spawn_point.gd
└── map_transition.gd

res://assets/tilesets/
├── forest_tiles.png
├── town_tiles.png
└── house_tiles.png

地图资源可能还有:

res://resources/tilesets/
├── forest_tileset.tres
├── house_tileset.tres
└── town_tileset.tres

如果你的 TileSet 是单独保存的 .tres,可以放这里。

24. systems 目录怎么放

scripts/systems 放当前场景内的系统脚本。

比如:

res://scripts/systems/
├── weather_manager.gd
├── time_manager.gd
├── interaction_system.gd
├── spawn_manager.gd
└── camera_controller.gd

这些不一定是 Autoload。

区别是:

当前地图里的天气效果节点
systems/weather_manager.gd

全局跨场景天气状态
autoload/weather_manager.gd

入门阶段可以简单点:

天气视觉效果放当前场景
长期全局状态以后再抽 Autoload

25. autoload 目录怎么放

res://scripts/autoload/
├── game.gd
├── scene_manager.gd
├── audio_manager.gd
├── save_manager.gd
├── settings_manager.gd
├── events.gd
├── item_database.gd
└── quest_manager.gd

如果 Autoload 是场景:

res://scenes/autoload/
├── audio_manager.tscn
└── scene_manager.tscn

注册名建议:

Game
SceneManager
AudioManager
SaveManager
SettingsManager
Events
ItemDatabase
QuestManager

代码里:

Game.add_gold(100)
SceneManager.change_scene("res://scenes/world/town.tscn")
AudioManager.play_sfx("click")

26. resources 脚本和 resources 数据要分开

这个命名有点绕。

scripts/resources/
放自定义 Resource 的脚本类型

resources/
放具体 .tres 数据

比如:

res://scripts/resources/item_data.gd
定义 ItemData 类型
res://resources/items/potion.tres
具体一瓶药水的数据

也就是说:

item_data.gd 是类
potion.tres 是实例数据

前端类比:

interface ItemData {
  id: string
  name: string
}

对应:

{
  "id": "potion",
  "name": "生命药水"
}

27. 文件命名建议

文件夹名

建议小写 + 下划线:

player
main_menu
item_database
dialog_box
weather_manager

脚本文件

建议小写 + 下划线:

player.gd
enemy.gd
weather_manager.gd
item_data.gd
scene_manager.gd

场景文件

也建议小写 + 下划线:

player.tscn
hud.tscn
dialog_box.tscn
inventory_panel.tscn

class_name

建议 PascalCase:

class_name Player
class_name Enemy
class_name ItemData
class_name WeatherManager
class_name SceneManager

对应关系:

文件item_data.gd
类名ItemData

文件weather_manager.gd
类名WeatherManager

文件dialog_box.gd
类名DialogBox

这样看起来最舒服。

28. 不建议的命名

不推荐:

PlayerScript.gd
NewNode2D.gd
test.gd
final_final_player.gd
玩家脚本.gd
场景1.tscn
新建场景2.tscn

不是 Godot 不允许,而是后面维护会难受。

推荐:

player.gd
player.tscn
town.tscn
forest.tscn
dialog_box.gd
inventory_panel.gd

命名要回答一个问题:

这个文件是干什么的

29. 场景命名和根节点命名

场景文件:

player.tscn

根节点建议叫:

Player

脚本:

player.gd

class:

class_name Player

整体对应:

player.tscn
Player root node
player.gd
class_name Player

这样非常清楚。

敌人:

slime.tscn
Slime root node
slime.gd
class_name Slime

如果多个敌人共用一个 Enemy 脚本,也可以:

slime.tscn
root node: Slime
script: enemy.gd
class_name Enemy
stats: slime_stats.tres

30. 什么时候一个目录一个文件

如果对象很简单:

chest.tscn
chest.gd

就可以直接放:

scenes/items/chest.tscn
scripts/items/chest.gd

不用专门建:

scenes/items/chest/chest.tscn

如果对象复杂,有很多相关素材、子场景、配置,可以建子目录。

比如玩家:

scenes/player/player.tscn
scripts/player/player.gd
assets/sprites/player/

比如复杂 Boss:

scenes/enemies/boss_dragon/
├── boss_dragon.tscn
├── boss_dragon_phase_1.tscn
└── boss_dragon_phase_2.tscn

31. 不要过早拆太细

你是前端开发,可能很容易想一开始就这样:

core/
domain/
infrastructure/
presentation/
features/
modules/
shared/

Godot 初期别这么搞。

游戏项目更重要的是:

能找到文件
能快速试东西
能稳定扩展

入门阶段建议:

先按 scenes/scripts/assets/resources
等某个模块真的变大再单独细分

过度设计很容易让你还没做出角色移动,就已经在和目录结构打 Boss。

32. 推荐的第一阶段最小结构

如果你现在刚开始搭地图和角色,其实只需要:

res://
├── scenes/
│   ├── main.tscn
│   └── player.tscn
├── scripts/
│   └── player.gd
├── assets/
│   ├── tilesets/
│   └── sprites/
└── resources/

等你加入 UI,再加:

scenes/ui/
scripts/ui/
assets/ui/

等你加入敌人,再加:

scenes/enemies/
scripts/enemies/
resources/enemies/
assets/sprites/enemies/

等你加入物品,再加:

scenes/items/
scripts/items/
resources/items/
assets/icons/

33. 推荐的第二阶段结构

当你已经有:

角色能走
地图能显示
镜头能跟随
宝箱能交互
HUD 能显示

可以变成:

res://
├── scenes/
│   ├── main/
│   ├── player/
│   ├── world/
│   ├── items/
│   └── ui/
├── scripts/
│   ├── player/
│   ├── world/
│   ├── items/
│   └── ui/
├── assets/
│   ├── sprites/
│   ├── tilesets/
│   ├── ui/
│   └── audio/
└── resources/
    └── items/

34. 推荐的第三阶段结构

当你开始做完整 RPG 系统:

res://
├── scenes/
│   ├── main/
│   ├── player/
│   ├── world/
│   ├── npcs/
│   ├── enemies/
│   ├── items/
│   ├── ui/
│   ├── systems/
│   ├── effects/
│   └── autoload/
├── scripts/
│   ├── player/
│   ├── world/
│   ├── npcs/
│   ├── enemies/
│   ├── items/
│   ├── ui/
│   ├── systems/
│   ├── autoload/
│   ├── resources/
│   └── utils/
├── assets/
├── resources/
├── shaders/
├── themes/
└── addons/

这个结构就能撑很久。

35. 场景依赖怎么组织

一个常见原则:

小场景不要反向依赖大场景

比如:

Chest 不应该知道 Main 在哪里
Enemy 不应该知道 HUD 在哪里
NPC 不应该知道 DialogBox 在哪里

更推荐:

Chest opened 信号
Main 监听 Chest.opened
HUD 负责显示金币

目录结构只是表面,真正的组织还包括依赖方向。

好的方向:

Main 组装 PlayerWorldUI
Player 管自己
Chest 管自己
HUD 管显示
Game 管全局状态

坏的方向:

Chest 直接 $/root/Main/UI/HUD 修改金币文字
Enemy 直接找 Player 的深层路径
NPC 直接控制 DialogBox 内部 Label

这种会越写越硬。

36. 推荐的依赖方向

可以记这个:

具体对象只管自己
上层场景负责连接对象
全局系统负责跨场景状态

比如:

Player
移动交互受伤死亡

Chest
打开是否已开发奖励信号

HUD
显示血量金币时间

Main
连接 Player.health_changedHUD.update_health
连接 Chest.openedGame.add_gold

Game
保存金币当前模式跨场景数据

37. scenes 和 resources 的依赖关系

常见关系:

Scene 引用 Resource
Resource 不要反过来依赖 Scene 实例

比如:

Enemy.tscn 引用 slime_stats.tres
SkillData.tres 引用 fireball_effect.tscn
ItemData.tres 引用 potion.png

可以。

但不要让 Resource 保存某个运行时节点:

@export var current_enemy_node: Enemy

这通常不合适。

Resource 适合保存:

配置
路径
PackedScene
Texture2D
AudioStream
数值
描述

不适合保存:

当前场景里的临时节点引用

38. 路径 res:// 和 user://

Godot 里常用两个路径前缀:

res://
项目资源路径

user://
用户数据路径

官方数据路径文档说明,res://user:// 是 Godot 项目里访问路径的两种重要记法,用来区分项目资源和用户数据位置。(Godot Engine documentation)

用法:

var texture = preload("res://assets/sprites/player/player.png")
const SAVE_PATH = "user://save.json"

简单记:

游戏自带文件放 res://
玩家生成或保存的数据放 user://

比如:

res://resources/items/potion.tres
药水配置游戏自带

user://save.json
玩家存档运行时生成

39. 不要把存档写到 res://

不推荐:

const SAVE_PATH = "res://save.json"

导出游戏后,res:// 通常不是给你随便写入玩家数据的地方。

推荐:

const SAVE_PATH = "user://save.json"

存档、设置、玩家截图这类都适合 user://

40. 版本控制建议

Godot 项目建议用 Git。

需要提交的通常是:

project.godot
scenes/
scripts/
assets/
resources/
shaders/
themes/
addons/

不建议提交:

.godot/
.DS_Store
临时导出文件
日志文件

官方版本控制文档也建议忽略 Godot 自动创建的生成数据,比如 .godot/。(Godot Engine documentation)

41. 什么文件适合 Git 管理

适合提交:

.tscn
.gd
.tres
.png
.webp
.ogg
.wav
.ttf
.gdshader
project.godot

.tscn.tres 是文本资源,适合版本控制和查看 diff。

不适合提交:

.godot/
导出后的 exe/app/html
临时测试文件
大体积缓存

42. 大资源怎么处理

如果你的项目以后有大量大文件,比如:

高清音频
大图
视频
大型模型

Git 仓库会变大。

可以考虑:

Git LFS
外部素材管理
只提交最终压缩资源

但你现在做 2D RPG 初期,不用一上来就搞复杂。

先保证结构清晰最重要。

43. 命名和路径不要频繁改

Godot 资源互相引用路径。

虽然 Godot 编辑器里移动文件通常会帮你维护引用,但还是建议:

尽量在 Godot 编辑器的 FileSystem 面板里移动文件
不要总是在系统文件管理器里乱拖
不要频繁改资源路径

尤其是 .tscn.tres、TileSet、Animation、Theme 这些资源引用比较多,路径乱改容易找不到资源。

44. 用 Godot 编辑器移动文件

推荐:

 Godot FileSystem 面板里移动重命名资源

而不是:

直接在 Finder / Windows 资源管理器里移动

这样 Godot 更容易维护资源引用关系。

如果你在外部移动了文件,Godot 可能需要重新导入,某些引用也可能丢。

45. 资源命名要稳定

比如物品 ID:

potion
iron_sword
fireball_card

不要今天叫:

red_potion

明天改:

hp_bottle_001

因为后面存档、配置、任务、掉落都可能引用它。

文件名可以调整,但 ID 尽量稳定。

比如:

@export var id: String = "potion"

这个 id 一旦用于存档,最好不要随便改。

46. 当前 RPG 项目推荐最小落地结构

你现在可以先创建这些:

res://scenes/
├── main.tscn
└── player.tscn

res://scripts/
└── player.gd

res://assets/
├── tilesets/
└── sprites/

res://resources/

等你要加入 UI:

res://scenes/ui/hud.tscn
res://scripts/ui/hud.gd
res://assets/ui/

等你要加入宝箱:

res://scenes/items/chest.tscn
res://scripts/items/chest.gd

等你要加入物品配置:

res://scripts/resources/item_data.gd
res://resources/items/potion.tres
res://assets/icons/potion.png

47. 一个适合你当前阶段的 main.tscn

你现在只需要:

Main Node2D
├── World Node2D
│   └── Ground TileMapLayer
├── Player
└── UI CanvasLayer

后面再逐步加:

Systems
NPCs
Enemies
Objects
Weather
Time

不要一开始就把所有系统都创建出来。

先保证:

地图能画
玩家能走
镜头能跟
碰撞能挡

然后再加玩法。

48. 一个清晰的项目演进顺序

建议你按这个顺序扩展目录和系统:

第一步
main.tscn
player.tscn
player.gd
基础 TileMapLayer

第二步
world/town.tscn
Camera2D
碰撞

第三步
ui/hud.tscn
hud.gd

第四步
items/chest.tscn
chest.gd
交互系统

第五步
npcs/npc.tscn
npc.gd
dialog_box.tscn

第六步
resources/item_data.gd
resources/items/*.tres
背包 UI

第七步:
enemies/enemy.tscn
enemy.gd
战斗和受伤

第八步:
autoload/game.gd
scene_manager.gd
save_manager.gd

第九步:
weather_manager
time_manager
season system

第十步:
card_data
卡牌系统

这样每一步都是可运行、可验证的,不会一下子把自己淹死。

49. 代码组织原则

一个脚本只负责一个主要对象

推荐:

player.gd 负责玩家
chest.gd 负责宝箱
hud.gd 负责 HUD
weather_manager.gd 负责天气

不推荐:

main.gd 同时负责玩家移动宝箱天气UINPC存档

对象自己的逻辑放自己身上

比如:

宝箱是否打开
 chest.gd

玩家是否能移动
 player.gd

HUD 怎么显示金币
 hud.gd

天气怎么切换
 weather_manager.gd

跨对象关系由上层连接

比如 Main:

func _ready() -> void:
    player.health_changed.connect(hud.update_health)
    chest.opened.connect(_on_chest_opened)

50. 新手最容易犯的结构错误

错误 1:所有文件都放根目录

不推荐:

res://player.gd
res://enemy.gd
res://slime.png
res://main.tscn
res://potion.tres

推荐分目录。

错误 2:assets 和 resources 混在一起

不推荐:

assets/potion.tres
resources/potion.png

推荐:

assets/icons/potion.png
resources/items/potion.tres

错误 3:脚本全放一个 scripts 根目录

项目小可以,但稍微大就乱。

不推荐:

scripts/player.gd
scripts/enemy.gd
scripts/chest.gd
scripts/hud.gd
scripts/dialog_box.gd
scripts/weather_manager.gd

推荐:

scripts/player/player.gd
scripts/enemies/enemy.gd
scripts/items/chest.gd
scripts/ui/hud.gd
scripts/systems/weather_manager.gd

错误 4:Main.gd 越写越大

Main 只做组装和协调。

不要让它变成几千行。

错误 5:Autoload 滥用

不要所有东西都全局化。

Player 不一定是 Autoload
Chest 不应该是 Autoload
NPC 不应该是 Autoload
HUD 通常也不应该是 Autoload

51. 推荐你的当前项目目录版本

如果让我现在给你一个最适合“刚开始做 RPG 地图和角色移动”的版本,我会给这个:

res://
├── project.godot
├── scenes/
│   ├── main.tscn
│   ├── player/
│   │   └── player.tscn
│   ├── world/
│   │   └── test_map.tscn
│   └── ui/
├── scripts/
│   ├── player/
│   │   └── player.gd
│   ├── world/
│   └── ui/
├── assets/
│   ├── sprites/
│   │   └── player/
│   ├── tilesets/
│   └── ui/
└── resources/

暂时不用建太多。

等你真的要做宝箱,再建:

scenes/items/
scripts/items/

等你真的要做敌人,再建:

scenes/enemies/
scripts/enemies/
resources/enemies/

52. 这一章你先记住这些

Godot 不强制项目结构但项目需要自己整理
scenes .tscn 场景
scripts .gd 脚本
assets 放图片音频字体等原始素材
resources .tres 配置资源
autoload 放全局系统
shaders 放着色器
themes UI 主题
addons 放插件
.godot 是编辑器缓存通常不要提交 Git
res:// 是项目资源路径。
user:// 是用户数据路径。
Main 负责组装当前场景不要变成上帝脚本
Autoload 负责全局服务不要变成全局垃圾桶

53. 最重要的一句话

目录结构的目的不是看起来高级”,而是让你三个月后还能知道每个文件该去哪找

再压缩一下:

场景对象scenes
对象逻辑scripts
原始素材assets
配置数据resources
全局服务autoload
用户存档user://

 

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

分享文章

相关文章

更多文章 →
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 官方文档也把节点和场景放在一起讲:多个节点组成树状结构后...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录