Defold 是一款引擎与编辑器一体的跨平台游戏开发工具,其内置 IDE 承载了从资源导入、场景搭建、脚本编写到打包导出的完整工作流。(Defold editor overview) 本文从编辑器操作层面出发,系统讲解 Defold 的资源管线:场景编辑器如何使用、图集如何优化包体、Prefab 与 Collection 如何复用,以及最终打包时如何控制体积与加载性能。
在开始之前,建议先通读 Defold 游戏引擎介绍:架构、特性与平台支持 了解引擎的整体定位,再结合本文上手编辑器。编辑器习惯与 Lua 脚本系统也紧密相关,可同步参考 Defold Lua 脚本系统深入。
一、Defold 编辑器总览与工作区
1. 下载与项目结构
Defold 编辑器无需独立安装引擎,下载即得完整开发环境。首次启动后通过 New Project 可选择空工程或官方模板(Side-scroller、Top-down、GUI 等)。一个典型工程的文件结构如下:
mygame/
├── game.project -- 全局配置:分辨率、引导场景、资源根目录
├── game.appmanifest -- 各平台依赖的权限与 App 配置(可选)
├── main/
│ ├── main.collection -- 引导集合,engine 启动时加载
│ └── main.script
├── assets/
│ ├── sprites/ -- 原始图片
│ ├── atlases/ -- .atlas 图集
│ ├── tile_sources/ -- .tilesource 瓦片源
│ └── sounds/
├── gui/
└── input/ -- .input_binding 输入绑定
关键文件 game.project 使用键值对格式,例如:
[display]
width = 1280
height = 720
[bootstrap]
main_collection = /main/main.collectionc
[project]
title = MyGame
2. 编辑器布局
打开工程后,编辑器分为几个主要面板:
- Assets 面板(左):以树形展示工程内全部资源,右键可新建场景、图集、脚本等
- Scene 面板(中):可视化编辑场景,支持平移、缩放、旋转对象,底部有坐标轴提示
- Outline 面板(右侧):列出当前场景内的 GameObject 与 Component 层级
- Properties 面板(右下方):选中对象后编辑其属性(位置、缩放、动画等)
- Console(底部):输出编译错误、Lua 打印与运行时日志
按住 Alt + 滚轮 缩放场景视图,按住鼠标中键拖拽平移。Defold 以「当前视图内的对象」为操作目标,配合 Outline 面板可精确选中重叠对象。
3. 场景的三类对象
编辑器中一切内容都围绕三类对象组织:
- Game Object:一个可挂载多个 Component 的实体
- Component:Sprite、CollisionObject、Script、GUI、Factory、Sound 等功能块
- Collection:多个 Game Object 的容器,本身也可作为实例被引用
创建流程通常是:右键 Scene 面板 → Add Game Object → 右键该对象 → Add Component 选择功能。例如给玩家加一个 Sprite(贴图)和一个 Script(逻辑)。
二、场景编辑器:从空场景到可运行关卡
1. 放置与变换
选中 Game Object 后,Properties 面板中的 Position、Rotation、Scale 控制其变换。也可以在 Scene 面板直接拖拽移动、按住 Q 键绕 Z 轴旋转。Ctrl + D 快速复制对象,Delete 删除。
坐标系统为右手系,2D 游戏通常把相机放在 Z 轴负方向,面向 XY 平面。创建相机 Camera 组件时,设置 Orthographic Projection 并调节 Zoom,让视口显示想要的区域。
2. 使用 Tilemap 搭建关卡
对于平台游戏的地面与墙壁,推荐使用 Tilemap 而非逐一摆放 Sprite:
- 准备一张瓦片图(PNG),创建
.tilesource资源,设置Tile Width、Tile Height、Margin与Spacing - 新建 Tilemap 组件,选择该 Tilesource
- 在 Scene 面板用瓦片刷绘制:
Shift拖拽连续画,Alt取色 - 为 Tilemap 挂
CollisionObject时,可选Tile Grid形状自动按瓦片生成碰撞
Tilesource 在 game.project 中默认会把所有瓦片合入同一张图集,大幅降低 Draw Call。
3. 场景内的层级与父子关系
在 Outline 面板拖拽一个 Game Object 到另一个下面,即可建立父子关系。子对象的 Position 是相对父对象的世界坐标偏移。移动父对象时,子对象会跟随。这一机制常用来做「角色 + 武器挂点」「载具 + 乘员」等结构。
要注意:Transform 是继承的,go.get_position() 返回的是局部坐标;需要世界坐标时使用 go.get_world_position()。
-- 获取子对象的局部与全局坐标
local local_pos = go.get_position("weapon_anchor")
local world_pos = go.get_world_position("weapon_anchor")
print(local_pos, world_pos)
三、图集与资源管理
1. 为什么需要图集
Defold 默认按图片文件逐个生成纹理,每张纹理一次 Draw Call。对于大量小图(图标、道具、动画帧),应放入 .atlas 图集统一合批,Draw Call 数量可减少一个数量级。(Defold atlas docs)
创建方式:右键 → New → Atlas,打开图集编辑器后把图片文件直接拖入。图集编辑器会自动计算排版(Max Size 可设 1024/2048/4096),下方会提示占用率。
2. 图集尺寸与平台限制
移动端对纹理尺寸有硬限制(老设备最大 2048,主流已到 4096)。图集超过上限时会自动拆分,但仍建议:
- 纹理尺寸保持 2 的幂(如 512×512),避免个别平台缩放开销
Extend Edges/Premultiply Alpha按需开启,避免放大时出现描边或亮边- 使用压缩格式时,优先选 ASTC(Android)、PVRTC(iOS 老设备)、WebP(Web)
3. 资源加载与引用
Defold 中资源通过 URL 路径引用,脚本里 factory.create("/main/enemy/enemy.factory") 即指向编译后的 .factoryc 资源。引用关系是「编译期解析」的:只要资源在工程内、路径正确,就能安全加载。
game.project 的 [resources] 段控制哪些目录被纳入构建:
[resources]
local = # 主资源目录(默认为空 = 工程根)
资源一旦被某脚本、集合或图集引用,就会被打进包。若某个资源从未被引用,则不会进入最终包体(这既是优势也是坑:忘记引用 = 功能缺失)。
4. 资源的动态加载
collectionfactory 与 collectionproxy 允许运行时动态加载资源(详见 热更新与热重载)。对体积大、非首屏的资源(如 BOSS 关卡、付费内容),用 collectionproxy.load() 延迟加载:
function init(self)
-- 预加载关卡代理
self.proxy = msg.url("/level_proxy")
msg.post(self.proxy, "load")
end
function on_message(self, message_id, message, sender)
if message_id == hash("proxy_loaded") then
msg.post("#", "enable")
elseif message_id == hash("proxy_unloaded") then
print("关卡已卸载,内存释放")
end
end
四、Prefab 与 Collection 复用
1. Defold 的「Prefab」在哪里
Defold 没有命名为 Prefab 的资源类型,其等价物是:
- 单个游戏对象复用:保存为一个
.go文件(工程内任意对象可Save As生成),场景中拖入即可实例化 - 多对象组合复用:保存为
.collection文件,可包含多个对象与嵌套子集合,是 Defold 最重要的复用单位
操作:选中对象 → 右键 → Save as GameObject/Collection,之后在其他场景中拖拽该资源即创建实例。
2. Collection 的实例化与命名空间
Collection 实例在场景中拥有独立命名空间(socket)。当集合被实例化多次(例如多个敌人波次),每个实例的 Game Object 都可通过 socket:path#component 访问。这种命名空间隔离让「同一模板多实例」不会互相冲突。
-- 通过 socket 地址访问集合实例内的对象
local url = msg.url("enemy_wave_1:/enemy#script")
msg.post(url, "activate")
3. 预制体的参数化
复用模板时往往需要传入差异参数。惯用做法是:在集合内的脚本里暴露 init 参数,实例化后通过 go.set() 或自定义消息配置:
-- enemy.go 的脚本
function on_message(self, message_id, message, sender)
if message_id == hash("configure") then
go.set("enemy", "tint", message.tint)
self.hp = message.hp
end
end
父级生成实例后立即发送配置消息:
local id = factory.create("/main/enemy/enemy.factory", go.get_position())
msg.post("enemy:" .. tostring(id) .. "#script", "configure", { hp = 30, tint = vmath.vector4(1, 0.2, 0.2, 1) })
4. 嵌套集合与模块化关卡
大型关卡可拆成「地面」「装饰」「敌人」「触发区域」多个子集合,再组合进一个总集合。好处:
- 不同美术/策划可并行编辑各自子集合,避免冲突
- 按需
collectionproxy加载,降低首屏内存 - 复用「房间」模板组装随机地牢或无限关卡
五、资源打包与优化
1. 构建过程:bob 与包体组成
编辑器 File → Bundle 调用底层构建工具 bob(java 程序)。构建产物是一个归档文件,内含:
- 存档里的资源:被引用的图集、场景、脚本等,按资源 ID 哈希索引
- 引擎可执行文件:不同平台的 runtime
- manifest:记录资源版本与校验和(Live Update 依赖)
包体 ≈ 引擎 runtime(约 1-2MB)+ 资源体积。因此优化包体的重点几乎全在资源侧。
2. 包体瘦身清单
- 砍掉未引用资源:用
bob --exclude或构建日志检查未使用资源 - 压缩图片:PNG 转 WebP/压缩格式;纯色 UI 可用 8bit 索引色
- 图集装箱率:尽量达到 90% 以上,避免浪费的空白区域
- 音频压缩:
game.project中开启 Vorbis/Opus 压缩(默认未启用) - 剔除调试数据:发布构建设置
strip_ir = 1剔除 Lua 调试信息
3. 加载性能优化
- 首屏只加载必要资源,后续内容用
collectionproxy懒加载 - 图集拆分:常驻 UI 一张,游戏内大图单独一张,避免「为了 1 张图加载 20MB」
- 使用
resource.create_archive_manifest与 Live Update 把大资源挪到服务端(见 Defold 热更新与热重载)
4. 构建配置片段示例
game.project 中与资源相关的高频配置:
[bootstrap]
main_collection = /main/main.collectionc
[display]
width = 1280
height = 720
[sound]
compression = 1 -- 启用音频压缩
preload_max_sounds = 64
[project]
version = 1.0.0
[liveupdate]
enabled = 1 -- 启用热更新支持
private_key = /path/private.der
六、团队协作与版本控制
1. Defold 与 Git
Defold 工程天然适合 Git 协作:场景、集合、图集等资源是文本格式(或带人类可读字段的二进制),编辑器内置了 File → Open Other Location → Show in... 便捷入口。
建议 .gitignore 忽略构建产物与缓存目录:
build/
cache/
*.collectionc
*.go.c
*.atlas.c
2. 避免编辑冲突的技巧
- 每人负责不同的
.collection/.go,减少同一文件并发修改 - 场景文件尽量「小而多」,避免巨型关卡文件被两个人同时拖拽
- 使用编辑器内置的 Merge 支持(基于文本 diff),冲突时以最新提交为准再合并
3. 从编辑器到 CI
官方提供 headless 构建:java -jar bob.jar --resolve --build --bundle 可在 CI 中产出多平台包。结合 DevOps 专题 的流水线实践,可实现「提交即构建、产物自动上传」的发布流程,具体可阅读 Defold 跨平台发布。
七、常见问题与排查
1. 图集里的图片显示异常
检查图集资源路径是否包含中文或特殊字符(某些平台构建会失败);确认图片为 RGBA 且尺寸非 0。开启 Premultiply Alpha 后,Shader 混色模式需匹配,否则会出现黑边。
2. 场景找不到资源
报错 Could not find resource 多为路径写错。确认脚本中使用的路径与 Assets 面板完全一致(注意 /main/main.collectionc 带 c 后缀,脚本引用时通常写无后缀路径,引擎自动补)。
3. 包体突然变大
多半是误引用了整张大图或整组资源。用构建日志定位「引用了哪些资源」,检查是否有脚本 require 了不该引用的模块,或图集包含了废弃素材。
八、总结
Defold 的资源管线是一条「引用驱动」的流水线:资源被引用才会进入包体,图集负责合批降 Draw Call,Collection 负责复用与模块化,Live Update 负责把体积挪到云端。掌握这四件事,基本就能搭建出体量可控、加载流畅、可多人协作的 Defold 工程。
后续建议结合 Defold Lua 脚本系统深入 理解资源在运行时的生命周期,配合 Defold 物理引擎 完善关卡交互,最终通过 Defold 跨平台发布 交付到各平台。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。