Defold 编辑器与资源管线:从场景搭建到包体瘦身

深入 Defold 编辑器的场景编辑器、图集与资源管理、Prefab/Collection 复用机制,以及资源打包与优化的完整管线实践。

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:

  1. 准备一张瓦片图(PNG),创建 .tilesource 资源,设置 Tile Width、Tile Height、Margin 与 Spacing
  2. 新建 Tilemap 组件,选择该 Tilesource
  3. 在 Scene 面板用瓦片刷绘制:Shift 拖拽连续画,Alt 取色
  4. 为 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 跨平台发布 交付到各平台。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「defold」更多文章

  1. Defold 音频系统:Sound 组件、背景音乐、3D 音效与声音管理
  2. Defold 精灵与动画:Sprite、Flipbook、缓动与程序动画
  3. Defold 着色器与后处理:GLSL 材质、特效与全屏后期