原文链接 https://zhuanlan.zhihu.com/p/28644268 

期待原作者上传至AssetStore.

今天,我的第一个 Unity 插件 MetaSprite 正式发布了它的 0.1 版本,所以想趁这个机会写一篇文章做下记录。

MetaSprite 是一个高效、灵活的 Aseprite to Unity 导入插件。它可以把像素动画软件 Aseprite 生成的 .ase 文件导入 Unity,作为 Mecanim 动画系统的 Animation Clip 和 Animator Controller 使用。

MetaSprite 不是第一个完成这件事的插件,但相较它的先来者(talecrafter/AnimationImporter),有以下的改进点和新功能:

  • 不依赖外部的 Aseprite 可执行程序以导入
  • 内建 ase 文件的 parser,因此导入速度非常的快,可以达到前者的10倍以上
  • 在创建图集(atlas)的时候会略去空白区域,大大提高了空间利用率
  • 更简单的工作流,通过右键菜单来实现导入
  • 导入设置单独存储,不需要在一个全局配置上改来改去
  • 完善的metadata(元数据)支持

项目的源代码在这里 WeAthFoLD/MetaSprite。接下来,我想简单说一说在开发这个插件过程中的一些想法和心得。

1. 动机

我在过去的一段时间一直和同学做一个像素风格的横版动作游戏。在多次试验试错之后,我们最终确定了以像素帧动画为核心表现形式,基于 Aseprite 绘制的帧动画进行导入的工作流。很长一段时间,我们用的是手动导入,通过 Aseprite 导出图集,然后在 Unity 里手动切图、设置锚点,再手动创建关键帧。这样的重复工作占用了大量的时间,导致动画编辑的效率一直上不去。现在想想,当时可谓是我们动画编辑的石器时代(雾)。

暑假,我在上海的一家独立游戏工作室实习。非常凑巧的是,这里同样使用了基于 Aseprite 的一套像素动画导入的工作流。但是这里的引擎大大写了一个非常棒的 ase 导入器(跑在基于lua的自研引擎上),把 ase 文件放在项目中就可以直接播放使用。

这样顺畅的工作流让我恍然大悟:如果在 Unity 里使用自动化工具进行 ase 文件的导入,那么会大大降低重复工作量,从而提高工作速度。我就此开始了 ase 导入工作流的探索。

初步的搜寻以后,我找到了 talecrafter/AnimationImporter 这一导入工具。初步使用起来感觉效果还行,但是有一些问题很大的影响了体验:

  1. 需要外部的 Aseprite 可执行文件来运行。这个工具通过调用 Aseprite 的 CLI-mode 来获取 ase 文件的 metadata 以及生成 atlas。这个过程相当消耗时间 (一个30帧左右的 ase 文件,在我的电脑上导入要5秒以上);
  2. 导入操作不符合直觉。我需要打开一个专门的 Animation Importer 窗口,然后把文件拖进去实现导入。并且导入设置是全局的,每次导入都要费力气把设置改来改去,可以预想到会消耗很多的时间;
  3. Aseprite 自己的 atlas 生成不是很给力,有大量留白。理想的状况是没有内容的区域全部忽略掉,让里面的 sprite 紧紧的贴在一起。

除此之外,我们还有一个最大的痛点没有被满足:通过 ase 文件来操纵一些非图像的数据。一个最典型的例子就是攻击判定框:因为我们是对反馈要求比较严格的动作游戏,碰撞框需要和动画比较好的同步,才能带来比较好的体验。对此,最好的方式就是美术直接在帧动画中绘制碰撞框。因此,我们需要某种方式来区别 ase 文件中的内容层和这种功能层,并对应的去解析这些层里的数据。

综上,现有的工具完全无法满足我对一个完善的 Aseprite 导入器的要ye求xin。自己造一个轮子的想法应运而生。

2. 开发小记

作为 proof-of-concept,我首先做的事是沿用 AnimationImporter 基本的工作流,并在上面加入自己的一些想法。也就是说核心还是调用 Aseprite 可执行文件,读取数据和生成,但会慢慢换掉其中的各个流程。

首先从最想做的 metadata 支持入手,设计了一些最基本的 metadata 规则,包括:

  1. 可以用 // 注释掉层或者动画片段(这里把frameTag译作动画片段,代表动画中的一段时间区间)
  2. 可以在动画片段名字后面用 #loop 让生成的 clip 循环播放
  3. '@' 字符开头的层是 meta层。meta层不会参与到 atlas 的生成,会被对应的 MetaLayerProcessor 读取并进行对应处理,比如说生成操纵 BoxCollider2D 的动画轨。

实现上,基本就是通过读取 Aseprite CLI 生成的 json 文件到一个 ASEMetadata 的数据结构中,然后再根据 metadata 进行接下来的 atlas生成 → clip生成 → controller生成 → 处理 meta layer。

工作流方面,实现了一个单独的导入配置文件作为 ScriptableObject 存在项目中。多个 ase 文件可以复用同一个导入配置,解决了之前在全局配置上改来改去的问题。导入的方式也改成了选择要导入的文件 -> 右键导入,便利了许多。

至此,这个项目的工作方式已经基本成型。我对新插件的工作流相当满意,除了一个严重的问题:慢。调用 Aseprite CLI 会带来不可避免的性能瓶颈。单生成一个 30 帧的 Atlas 就花了3秒左右的时间,Unity 导入这个 atlas 又要花去一秒多的时间。如果一个文件里有多个 meta 层的话,每个 meta 层在处理过程中都要单独生成一个 atlas,最后的时间消耗是非常恐怖的。因此,我最终还是下定决心,从头写一个自己的 ase 文件解析器,一劳永逸的解决性能上的问题。

非常幸运的是,aseprite 的官方 repo 里就有文件格式的描述文档(aseprite/aseprite),文件格式也很简单,因此在写 parser 的过程中阻力很小,连带 parser 和一个简单的 atlas generator 在一个周末的时间就写完了。最后的效果也很振奋人心,导入的时间从 5 秒以上起步变到了基本可以忽略不计(1秒以内)。

最后的大致效果可以看下面的演示:

3. 公开发布和未来计划

在这个工具做到一半的时候,我们的美术同学就开始怂恿我把这个东西公开出来。我自己也非常的看好这个工具,因为它真的切切实实解决了我们项目工作流的核心痛点。因此,在插件基本成型之后,我选择把它尽快公开,一方面希望这个工具可以让更多有和我们同样问题的开发者的需求得到解决,一方面希望能得到更多改善这个工具的建议。最终目标:让 MetaSprite 成为最好的 Aseprite to Unity 导入工具!

这个工具在 alpha 阶段会一直免费并且 MIT 开源,持续的对这个插件进行改进。毕竟作为一个刚成型的插件,还有很多重要的feature没有完工。

如果你和我一样也是一个 Aseprite 使用者和 Unity 开发者,也希望你能受益于这个工具,并且对这个工具提出各方面的批评建议。You will be my biggest motivation :-)

[转载]一个高效简洁的Aseprite to Unity导入工具的更多相关文章

  1. 通过Vim+少量插件配置一个高效简洁的IDE

    最近本人在看<TCP/IP Illustrated Volume2:The Implementation>这本书,自然要下载4.4BSD-Lite的源代码配合书本一起研读.以前学习Vim的 ...

  2. GJM:Unity导入百度地图SDK [转载]

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  3. Android:一个高效的UI才是一个拉风的UI(二)

    趁今晚老大不在偷偷早下班,所以有时间继续跟大伙扯扯UI设计之痛,也算一个是对上篇<Android:一个高效的UI才是一个拉风的UI(一)>的完整补充吧.写得不好的话大家尽管拍砖~(来!砸死 ...

  4. 成为一个高效的web开发人员,只需要三步

    想成为一名专业的web开发人员并不像你想象的那么容易,开发人员在开发自己的web项目时常常需要牢记很多东西,他们要不断寻找新理念,新创意,在特定时间内开发出高质量的产品,一名优秀的程序员必须明白时间的 ...

  5. 想成为一个高效的Web开发者吗?来看看大牛分享的经验吧~ #精选JAVASCRIPT前端开发

    想成为一个高效的Web开发者吗?来看看大牛分享的经验吧~ 作为一个软(ku)件(bi)工(de)程(ma)师(nong),你有没有觉得做什么事都没时间?没时间学习新东西,没时间去回顾.整理原来写的烂代 ...

  6. 发布一个高效的JavaScript分析、压缩工具 JavaScript Analyser

    发布一个高效的JavaScript分析.压缩工具 JavaScript Analyser 先发一段脚本压缩示例,展示一下JSA语法压缩和优化功能. try { //xxxx(); } catch (e ...

  7. .Net 高效开发之不可错过的实用工具(转)

    .Net 高效开发之不可错过的实用工具(转) 本文摘自: http://www.cnblogs.com/powertoolsteam/p/5240908.html#3372237 Visual Stu ...

  8. .NET 高效开发之不可错过的实用工具(第一的当然是ReSharper插件)

    工欲善其事,必先利其器,没有好的工具,怎么能高效的开发出高质量的代码呢?本文为 ASP.NET 开发者介绍一些高效实用的工具,包括 SQL 管理,VS插件,内存管理,诊断工具等,涉及开发过程的各个环节 ...

  9. NET 高效开发之不可错过的实用工具(第一的当然是ReSharper插件)

    工欲善其事,必先利其器,没有好的工具,怎么能高效的开发出高质量的代码呢?本文为 ASP.NET 开发者介绍一些高效实用的工具,包括 SQL 管理,VS插件,内存管理,诊断工具等,涉及开发过程的各个环节 ...

随机推荐

  1. git1使用步骤初始化拉取修改提交推送

    Git 使用 git init 命令来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行,所以 git init 是使用 Git 的第一个命令. 在执行完成 git init  ...

  2. springBoot 项目war包部署及改为war包后资源路径错误问题

    参考资料: https://blog.csdn.net/rico_zhou/article/details/83415114 https://blog.csdn.net/pz641/article/d ...

  3. MATLAB 符号变量表达式 + 方程求解

    源代码见文末 部分源代码: % 符号变量 两种表达方式 a=sym('a'); class(a); syms b; b; % 符号常量 c=sym('); c; % 符号表达式 三种表达方式 f1=' ...

  4. YY的GCD

    YY的GCD 给出T个询问,询问\(\sum_{i=1}^N\sum_{j=1}^M(gcd(i,j)\in prime)\),T = 10000,N, M <= 10000000. 解 显然质 ...

  5. 非阻塞tcp服务器与阻塞的tcp服务器对比

    一般的tcp服务器(阻塞)是使用的如下 [erlang] gen_tcp传输文件原型 http://www.cnblogs.com/bluefrog/archive/2012/09/10/267904 ...

  6. 【Java】【13】两个double类型比较大小

    /** * @return >0,第一位数大 */ public static int compare(double double1, double double2) { BigDecimal ...

  7. 通过 txt 文件批量导入需要批量处理的数据的标识字段

    前言 在一些工作中,可能需要对数据库中的一些数据(批量)进行处理(修改或者查询),而数据的来源是你的同事,换句话说就是这批数据不可能通过某些查询条件查出来, 而这批数据又比较多,比如几百.几千甚至几万 ...

  8. SqlServer 查看最近执行过的语句

    查看系统中最近执行的语句 ST.text AS '执行的SQL语句', QS.execution_count AS '执行次数', QS.total_elapsed_time AS '耗时', QS. ...

  9. leetcode 78,236,300

    ---恢复内容开始--- 2018.3.16目前已刷27题,打卡记录有意思的题目. leetcode78 subsets 思路1:DFS遍历子集,每遇到一个数就把该数加上原来的子集变成新的子集. cl ...

  10. jquery 浮动 固定显示

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>无标题文档 我爱b ...