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 行为树与游戏 AI 决策
  2. Defold 材质与着色器语言详解
  3. Defold HTML5 导出与 Web 性能优化