第一部分 12:项目结构和代码组织
这一章讲 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 里的配置资源,比如 ItemData、SkillData、WeatherData。
举例:
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 的职责是:
组合当前场景
连接 Player、HUD、World、Systems
处理当前地图内的对象关系
不要让 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 组装 Player、World、UI
Player 管自己
Chest 管自己
HUD 管显示
Game 管全局状态
坏的方向:
Chest 直接 $/root/Main/UI/HUD 修改金币文字
Enemy 直接找 Player 的深层路径
NPC 直接控制 DialogBox 内部 Label
这种会越写越硬。
36. 推荐的依赖方向
可以记这个:
具体对象只管自己
上层场景负责连接对象
全局系统负责跨场景状态
比如:
Player:
移动、交互、受伤、死亡
Chest:
打开、是否已开、发奖励信号
HUD:
显示血量、金币、时间
Main:
连接 Player.health_changed → HUD.update_health
连接 Chest.opened → Game.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 同时负责玩家移动、宝箱、天气、UI、NPC、存档
对象自己的逻辑放自己身上
比如:
宝箱是否打开
放 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://
如果您觉得这篇文章有帮助,请点个赞吧~
评论
请登录后发表评论
去登录