找回密码
 注册帐号

扫一扫,访问微社区

暂存 轻松导入2D作品到Unity里的工作流程(一)

18
回复
7820
查看
[ 复制链接 ]
排名
1
昨日变化

1591

主题

3670

帖子

1万

积分

Rank: 16

UID
2
好友
123
蛮牛币
3137
威望
121
注册时间
2013-5-19
在线时间
2320 小时
最后登录
2019-8-22

原创先锋

2014-6-3 15:40:26 显示全部楼层 阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
第一步,制作与输出
作者: Brett Bibby - 资深Unity原厂讲师

在去年有许多高质量的2D游戏采用Unity来开发,这篇文章是我在亚洲Unite三个国家(韩国、中国、日本)所演讲的内容再做个更深入、更实际的2D制程深入介绍,希望可以帮助到那些正在用Unity制作2D游戏和多媒体互动内容的读者,由于长度关系我把它分成两篇文章,本篇文章你可以了解有关制作规则和输出脚本制作的方式,下次我会介绍汇入Unity的部分,文章的最后也有我项目的下载点。


一个好的工作流程对于2D作品的好处

这个教学会带你操作一个产品真正工作流程,所谓工作流程,代表从最初的制作到游戏完成的所有步骤过程,不管中间使用了多少软件,一个高阶的工作流程主要由三个步骤组成: 制作、输出和输入。有些人可能觉得很奇怪,像Unity这样的工具可以直接汇入资料为何我们还需要自制输出器和汇入器,因为我们要自己建立两个应用程序之间的中介档案,让应用程序之间好像用胶水似的黏再一起让档案在中间无痛转换,在本范例就用Unity和Photoshop来当范例。这样就不需要额外的应用程序来读取或转换原生格式,并让内容转换到下一个应用程序。


制作

万物皆始于一个好的内容,首先的工作流程需要使用业界标准的Photoshop。Photoshop是很简单上手,用来建立和编辑图形也很轻松方便,有需求也可以选用像是Arsenal这样的脚本工具插件,问题是2D图档本身不像大多数3D模型可以带有中介数据(meta-data,注一),更重要的是,2D本质上因为只有像素数据的限制,因此必需要更多的中介数据来诠释。所以我们要做的是帮这些图形补充一些有用的说明,让我们最终在游戏里有效运用这些图形,要做到这点我们可以使用群组和图层来管理这些图形。

我们需要一个作品的实际案例来示范,在我加入Unity之前参与了一个2D的寻宝游戏,叫做Goddess Chronicles(女神编年史),我将用它做为例子,它就是就是一个在场景里面寻找隐藏的物品的游戏,如同下图所示


轻松导入2D作品到Unity里的工作流程

轻松导入2D作品到Unity里的工作流程


根据你制作的游戏性质不同,你的中介数据需求也会不相同,本范例会有"布景"和"物品"两种主要图形类型。

图层的重要性

布景是没有互动的图形,占据游戏大部分的空间用来传达关卡主题,并让那些互动物品可以隐藏在游戏环境里,因此所有布景类的图都会被命名为"scenery"开头的群组,因为它没有互动性我们就不用管图在该群组的图层分配。而在游戏里面用来寻找的物品会被命名为"item"开头的群组,不像布景,物品群组内的图层是很重要的,每个物品群组里最多有四种图的型态


以下是四种型态(请下载范例项目,并开启Assets/Hidden Object Game/Levels/GreeK Hall/Greek Hall.psd做对照)


"Whole"这个图层用来呈现整个物品,通常物品被找到时会有一些放大缩小或把物品移到道具栏的特效,所以我们需要整个物品图才不会破图。


“Obscured” 这个图层用来呈现物品在另外一个对象背后的感觉,因为物品图层是在前面,所以要擦除迭到的图像才会感觉跑到后面,理论上,你当然可以用Whole的图来取代,但是要美术去为了藏一个物品另外画许多分离的部件是很麻烦的事,而且保持最小的图量也能增进游戏效能。


"Shadow"图层是用来让物品在视觉比较融入场景,Shadow不归纳在Obscured或Whole而独立存放,因此图像被放大或移动时后面不会有块奇怪的阴影,玩家找到物品时反而我们只需要把阴影隐藏就好。


"Hotspot"图层用来增加或减少物品的点击范围,例如,如果在场景里藏一个高尔夫球杆会很难点到,使用hotspot图层就可以加大点击区域。


我们可以使用群组来集合这些图形并指定那些是布景或那些是物品,群组内最少要用一个图层存放Whole的图,依照需求也可以加入Obscured,Shadow,Hotspot图层,底下的截图说明了布景和物品的图层结构,物品的群组标名"item:Beads" 它包含名为"Whole"和"hotspot"的图层。底下布景的群组标名"Scenery:Column"它包含一些可以随便命名的前景图。


轻松导入2D作品到Unity里的工作流程

轻松导入2D作品到Unity里的工作流程

最后结果是我们完成了一个游戏的群组和图层结构,接下来就是输出了
你可以下载范例研究并回顾章节


输出

一旦我们做出了内容之后,我们就需要将这些成果转移到下一个软件流程来处理,本范例就是转入Unity,我们想要导出有描述场景位置、顺序和其他信息的中介数据图形,为了做到这点需要和应用程序做比较进阶的互动,幸运的是,Photoshop可以用Javascript来编写一些脚本,这正是我们需要的。


事实上,有许多Adobe的软件支持脚本编写,像是Fireworks,Illustrator,Flash或其他的软件,我们可以使用这些功能来写我们要给Unity的输出规格,包含我们需要用到的中介数据,而Adobe提供了一套叫做ExtendScript for Free的软件用来编辑脚本和除错。

ExtendScript for free下载网址 http://www.adobe.com/devnet/scripting.html


如果你有Creative Suite,那这个编辑器可能已经装在你计算机了,MAC的CS6会在Utility/Adobe Utilities - CS6/ExtendScript Toolkit CS6目录
Windows会在C:\Documents\Application Data\Adobe\ExtendScript Toolkit\3.8.


在Photoshop里很多东西可以透过脚本来处理,如果没有任何一个API是你需求的,那也可以用录制Action然后转换为程序代码在贴到脚本里(例如Alpha Channel的操作)


对于本范例而言,我们的脚本需要处里以下内容

           1.检查是否档案有开启
           2.确认文件有图层可以输出
           3.提示用户输出文件的位置
           4.循环处理每个图层,删除空白图层、存盘图片、并产生一个XML格式纪录位置和文件名的档案。
           5.最后把XML存档

最终版的输出脚本在教学包里有附,要使用这个脚本只要把档案放在Photoshop里的Presets/Scripts里面并建立一个子目录存着,这里不解释每一行的功能因为脚本里会有批注,但我会说明一些比较重要的部分

首先,脚本是用Javascript编写的,很容易学习和使用,由于Adobe附的Javascript引擎不是很快,但它运作正常并且可以用ExtendScript编辑器除错,所以够我们用。

由于中介数据是存放图形含意的重要数据,因此我们需要花点时间来想我们需要怎样的中介数据格式,我使用XML来作为中介资料的格式,因为我可以在Unity里面很轻易的解析转换XML,根据本游戏设计,我们需要中介数据格式看起来会是这样:


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <HogScene xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  4.         <layers>
  5.                 <Layer>
  6.                         <type>Scenery</type>
  7.                         <name>Scenery 01-4 background</name>
  8.                         <images>
  9.                                 <Image>
  10.                                         <type>Whole</type>
  11.                                         <name>Scenery Tree.png</name>
  12.                                         <x>25</x>
  13.                                         <y>63</y>
  14.                                 </Image>
  15.                         </images>
  16.                 </Layer>
  17.                 ...
  18.         </layers>
  19. </HogScene>
复制代码


所以我们的脚本会不断的产生这样的XML格式,并在在最后存成一个档案


输出脚本参考位置在Assets/Hidden Object Game/Photoshop Exporter/Export Unity Hidden Object Scene.jsx


在我们的输出脚本里,开头会建立一些方便使用的变量然后呼叫Main函式。基本流程是由上到下评估并执行,网络上常看到有些范例会把功能写成函式,有些直接写在脚本,我习惯把所有功能都放在函式里然后在一开始呼叫。



在Main函式里有许多有意思的部分,第一个部分是下列这行程序

  1. duppedPsd = app.activeDocument.duplicate();
复制代码

复制文件内容到duppedPsd结构,整个运作使用duppedPsd对象


执行复制文件原因有二,在Photoshop做任何的变动包含展开或收起群组都会让文件被标记为已异动,如果我们不这样做,输出过程中文件会被标记已异动,这导致当关闭文件时会被询问是否要存盘,美术可能不确定有没有改变内容就存盘,会造成存盘时间比最后版本还新而导致版本控制不易,开发者将不确定是否需要重新输出版本,导致开发效率降低,透过复制文件到结构就算有问题也是输出过程的错误而不会影响原始文件。第二个原因是输出过程有时总会会出错,而用这方法就可以还原到最初的状态。


有意思的还有这行:

  1. removeAllTopLevelArtLayers(duppedPsd);
复制代码

由于我们目前只需要有群组分类的图层,但仍可让美术制作一些角色、教学或是接口放在最上面的图层(根目录),所以我们用这行语法来清除那些没有要结构化的图层。



除此之外,主函式里会呼叫输出函式建立中介数据的XML文件,最后会存成档案
输出函式(exportLayerSets)是一个递回函式,递归函式如果需要会呼叫自己,继续"深入"我们的群组里找出场景中深层的对象

  1. function exportLayerSets(obj)
  2. {
  3.         for(var i = obj.layerSets.length-1; 0 < = i; i--)
  4.         {
  5.                 exportLayerSets(obj.layerSets[i]);
  6.         }
  7.         ...
  8. }
复制代码

这段语法重最后的图层不断往前复循环检查群组列表,如果群组里面还有群组,它就会继续再深入呼叫自己检查这个群组,由于Photoshop里最底层列表显示是在第一层,列表层次越高的群组则代表显示层次越低,因此我们从后面往前处理。


一旦分析到组名有"item"、"custom"(界面或角色图)就会进入各自的函式,其他都会被归类为scenery

  1. if(obj.name.search("item:") >= 0)
  2. {
  3.         ...
  4. }
  5. else if(obj.name.search("custom:") >= 0)
  6. {
  7.         ...
  8. }
  9. else // must be a scenery group
  10. {
  11.         ...
  12. }
复制代码

如果进入item,程序会循环检查图层,看看有没有刚刚讲的四种类别


  1. // process layers
  2. for(var layerIndex = 0; layerIndex < obj.artLayers.length; layerIndex++)
  3. {
  4.         sceneData += "<Image>";
  5.         obj.artLayers[layerIndex].visible = true;
  6.         switch(obj.artLayers[layerIndex].name)
  7.         {
  8.                 case "hotspot":
  9.                         saveScenePng(...);
  10.                 break;
  11.                 case "obscured":
  12.                         saveScenePng(...);
  13.                 break;
  14.                 case "shadow":
  15.                         saveScenePng(...);
  16.                 break;
  17.                 case "whole":
  18.                         saveScenePng(...);
  19.                 break;
  20.         }
  21.         obj.artLayers[layerIndex].visible = false;
  22.         sceneData += "</Image>";
  23. }
复制代码


当我们找到某些物品想要存起来,就呼叫存档函式来存成PNG格式,这个函式会先裁除影像左边和上面的空间用来判断XY坐标,再裁掉右边和下面

的空间然后存盘,并把中介数据放入XML字符串


  1. function saveScenePng(psd, imageType, fileName)
  2. {
  3.         // we should now have a single art layer if all went well
  4.         psd.mergeVisibleLayers();
  5.         // figure out where the top-left corner is so it can be exported
  6.         // into the scene file for placement in game
  7.         // capture current size
  8.         var height = psd.height.value;
  9.         var width = psd.width.value;
  10.         var top = psd.height.value;
  11.         var left = psd.width.value;
  12.         // trim off the top and left
  13.         psd.trim(TrimType.TRANSPARENT, true, true, false, false);
  14.         // the difference between original and trimmed is the amount of offset
  15.         top -= psd.height.value;
  16.         left -= psd.width.value;
  17.         // trim the right and bottom
  18.         psd.trim(TrimType.TRANSPARENT);
  19.         // find center
  20.         top += (psd.height.value / 2)
  21.         left += (psd.width.value / 2)
  22.         // unity needs center of image, not top left
  23.         top = -(top - (height/2));
  24.         left -= (width/2);
  25.         // save the image
  26.         var pngFile = new File(destinationFolder + "/" + fileName + ".png");
  27.         var pngSaveOptions = new PNGSaveOptions();
  28.         psd.saveAs(pngFile, pngSaveOptions, true, Extension.LOWERCASE);
  29.         psd.close(SaveOptions.DONOTSAVECHANGES);

  30.         // save the scene data
  31.         sceneData += ("<type>" + imageType + "</type>
  32.                                 <name>" + fileName + ".png</name>
  33.                                 <x>" + left + "</x><y>" + top + "</y>");
  34. }
复制代码


当我们执行输出时,完成的结果应该是有了裁切完成的PNG图形并伴随著名为Greek Hall.xml的XML文件,如下图所示
本范例位置在Assets/Hidden Object Game/Levels/GreeK Hall/Greek Hall.xml


7.png

现在,我们成功的输出了我们所有的图像和中介数据,接下来就可以到Unity输入这些档案了
注一:meta-data(中介数据),意思是用来诠释补述数据本身的延伸数据,在本范例就是XML文件,用来补充描述2D图形的定位坐标、名称和群组分类,在汇入Unity可以直接被分析的额外数据


本范例项目文件可从这个连结下载:点击此处


>>>轻松导入2D作品到Unity里的工作流程(二)<<<













unity 5.3 ;unity怎么导入;unity工作要求;unity使对象隐藏;unity导入模型贴图;unity www 图片;unity下载文件;free unity 3d assets;unity支持什么格式;unity支持哪些模型;mac unity c;unity 用什么图片格式;unity scripting api;unity如何导入assets;unity 简单游戏;unity场景下载;unity中xml操作;unity out;unity移除脚本;unity怎么导入插件;uni;unity 5 2d;unity导入在哪;unity导入;unity导入后怎么看;unity刚工作;unity隐藏对象;unity 模型贴图导入;unity www 上传图片;www unity 图片;unity 文件下载;unity 3d assets free;unity支持的格式;unity支持格式;unity支持 模型;unity支持的模型;mac unity c#;unity mac c;unity mac c#;unity图片格式;scripting api unity;unity 导入assets;unity最简单的游戏;unity在哪儿下载场景;unity操作xml;unity中out;unity移除所有脚本;unity导入插件;unity如何导入插件;怎么把插件导入unity;unity 下载图片;unity 判断对象被点击;unity支持的模型格式;unity如何删除项目;unity怎么删除项目;unity游戏界面没有显示;unity find;unity 不显示阴影;如何学习unity api;游戏制作软件 unity;unity find object;unity original;unity中变量类型;unity软件下载;unity怎么导入场景;unity 多场景编辑;unity插件不执行;unity 点击模型;unity www 本地文件;unity导入包;unity做app;unity free assets;unitypackage导出;unity制作开始界面;unity使用3d模型格式;unity角色控制与脚本;unity 5 版本控制;unity版本控制;unity 放大图片;unity url下载;unity导入项目;unity如何导入项目;unity项目导入打开;unity。 xml 存档;unity场景贴图;unity meta文件;unity代码怎么写;unity 前景;unity导入3d模型;unity 显示图片;unity c盘;unity instance;unity 3d导出模型;unity模型不显示;unity 程序最小化;unity 隐藏 显示;unity layer
回复

使用道具 举报

排名
16594
昨日变化

5

主题

35

帖子

95

积分

Rank: 2Rank: 2

UID
6
好友
0
蛮牛币
349
威望
20
注册时间
2013-5-24
在线时间
13 小时
最后登录
2015-8-25
2014-6-3 16:16:44 显示全部楼层
{:3_46:}{:3_46:}
回复

使用道具 举报

排名
16594
昨日变化

5

主题

35

帖子

95

积分

Rank: 2Rank: 2

UID
6
好友
0
蛮牛币
349
威望
20
注册时间
2013-5-24
在线时间
13 小时
最后登录
2015-8-25
2014-6-3 16:20:48 显示全部楼层
参与人数 1蛮牛币 -4 收起 理由
admin -4 淡定! 无意义回复!!!

查看全部评分总评分 : 蛮牛币 -4

回复

使用道具 举报

1

主题

9

帖子

51

积分

Rank: 2Rank: 2

UID
179
好友
0
蛮牛币
22
威望
10
注册时间
2013-6-3
在线时间
0 小时
最后登录
2013-6-3
2014-6-3 16:22:24 显示全部楼层
好帖 好教程
回复 支持 反对

使用道具 举报

4四处流浪
452/500
排名
10343
昨日变化

1

主题

159

帖子

452

积分

Rank: 4

UID
24
好友
7
蛮牛币
216
威望
-3
注册时间
2013-5-28
在线时间
190 小时
最后登录
2019-7-10
QQ
2014-6-3 17:03:06 显示全部楼层
翻译的不错~
回复 支持 反对

使用道具 举报

排名
1
昨日变化

199

主题

827

帖子

9684

积分

Rank: 16

UID
1
好友
26
蛮牛币
6658
威望
10
注册时间
2013-5-14
在线时间
3427 小时
最后登录
2019-7-26

一贫如洗游戏蛮牛QQ群会员活力之星

2014-6-3 17:50:13 显示全部楼层

不错 不错 不错
回复 支持 反对

使用道具 举报

排名
1
昨日变化

199

主题

827

帖子

9684

积分

Rank: 16

UID
1
好友
26
蛮牛币
6658
威望
10
注册时间
2013-5-14
在线时间
3427 小时
最后登录
2019-7-26

一贫如洗游戏蛮牛QQ群会员活力之星

2014-6-3 17:50:15 显示全部楼层

不错 不错 不错
回复 支持 反对

使用道具 举报

排名
1
昨日变化

199

主题

827

帖子

9684

积分

Rank: 16

UID
1
好友
26
蛮牛币
6658
威望
10
注册时间
2013-5-14
在线时间
3427 小时
最后登录
2019-7-26

一贫如洗游戏蛮牛QQ群会员活力之星

2014-6-3 17:50:20 显示全部楼层

不错 不错 不错
回复 支持 反对

使用道具 举报

排名
1750
昨日变化

35

主题

328

帖子

1546

积分

Rank: 9Rank: 9Rank: 9

UID
54
好友
23
蛮牛币
3307
威望
30
注册时间
2013-5-29
在线时间
375 小时
最后登录
2018-5-7
QQ
2014-6-4 15:10:31 显示全部楼层
很好很强大!赞一个
回复 支持 反对

使用道具 举报

7日久生情
1709/5000
排名
922
昨日变化

13

主题

310

帖子

1709

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
97
好友
4
蛮牛币
3958
威望
30
注册时间
2013-5-30
在线时间
265 小时
最后登录
2019-6-12
2014-6-7 19:17:26 显示全部楼层
不错不错。。。。
回复 支持 反对

使用道具 举报

5熟悉之中
632/1000
排名
4129
昨日变化

4

主题

86

帖子

632

积分

Rank: 5Rank: 5

UID
167
好友
3
蛮牛币
1286
威望
30
注册时间
2013-6-2
在线时间
180 小时
最后登录
2017-11-9
2014-6-8 16:00:41 显示全部楼层
相当受用
回复 支持 反对

使用道具 举报

5熟悉之中
632/1000
排名
4129
昨日变化

4

主题

86

帖子

632

积分

Rank: 5Rank: 5

UID
167
好友
3
蛮牛币
1286
威望
30
注册时间
2013-6-2
在线时间
180 小时
最后登录
2017-11-9
2014-6-8 16:01:02 显示全部楼层
相当受用
回复 支持 反对

使用道具 举报

排名
11659
昨日变化

0

主题

125

帖子

306

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
457
好友
0
蛮牛币
599
威望
0
注册时间
2013-6-24
在线时间
97 小时
最后登录
2018-11-21
2014-6-24 22:49:43 显示全部楼层
学习了,感谢楼主分享
回复 支持 反对

使用道具 举报

7日久生情
2079/5000
排名
598
昨日变化

0

主题

458

帖子

2079

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
3744
好友
0
蛮牛币
4982
威望
0
注册时间
2013-9-12
在线时间
240 小时
最后登录
2016-5-20
2014-9-17 09:55:00 显示全部楼层

看看,学习学习
回复 支持 反对

使用道具 举报

7日久生情
2079/5000
排名
598
昨日变化

0

主题

458

帖子

2079

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
3744
好友
0
蛮牛币
4982
威望
0
注册时间
2013-9-12
在线时间
240 小时
最后登录
2016-5-20
2014-9-21 18:27:26 显示全部楼层
学习了。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则