您的位置:首页 > 移动开发 > Unity3D

Unity下SpriteSheet 使用

2015-12-02 19:21 281 查看
原创文章, 转载请注明出处!

最近手头的Unity项目, 用到了特效和简单人物动作的部分, 其中涉及到大量的美术序列帧资源SpriteSheet. unity原生太这等资源的管理感觉不是太好. 自己做了个工具来部分解决这个问题. 这里记录一下以备忘, 顺便分享一下, 希望能帮助到需要的人.

一般的游戏引擎对这样一批同类的资源管理, 都会用到SpriteSheet, 或者支持SpriteSheet.就是把同类的序列帧小图拼成一张巨大的图片,另外还有一个数据文件文件,这个文件可能是json格式、xml格式、plist格式或其它。它记录了每帧在这张大图里的位置、大小、内部偏移,旋转等信息。

Unity自带功能支持

unity自己也支持, 只不过它做的很不明显。 它的操作方式如下

- 操作,选中同类的图片资源,,赋以相同的Packing Tag"名字

- 查看,可以在Windows->Sprite Packer中查看

- 结果,打出包来,会发现容量减少了许多, 说明起作用了

但它的问题是, 在Project视力下, 资源独立的,这样看起来, 很不爽。



我希望是这样的



另外,如果每一帧的大小是固定的,而且没有透明区域,他合成的大图,也可以用unity自带的功能切出来。

它支持自动切隔(用透明区域分隔),以特定大小的格子分隔。

比如同类的图标可以用到这个功能。但它的限制也是明显的。

第三方的Importer

常用SpriteSheet制作工具TexturePacker, 官方就出了一个TexturePacker Importer.

用了一些,使用很方便,功能上也没任何问题。只有一点。 它只支持*.tpsheet格式。 而这个格式只有TexturePacker的较新的几个版本,才能导出这种格式。 而且这个软件是收费的。

虽然收费, 它不得不说,它做的真好。各种多的功能,漂亮的UI,很棒的体验。十分推荐大家用一下。

多说一句,tpsheet格式。虽然是明文的, 但不太易读懂。我小人之心地猜想一下,这可能是作者故意的。



其它第三方的Importer. 也有一几个,支持的不好。

自己搞一个

参考别人已有的SpriteSheetSplit. 写了符合自己需求的一个。

首先Unity 在这方面提供的核心Api类 SpriteMetaData, 是不支持旋转的。

- 外部工具,比如TexturePacker导出时, 不能翻转 取消"Allow Rotatioin" 或 "Auto Roration"

- XY值, 外部工具以左上角为(0,0) X向右为正 Y向下为正 ; SpriteMetaData以左下角开始

- Pivot, 它的意思是物休旋转或放置时的参考点.

再说白一点,就是以物体上(都不一定在物体上)的哪个点为准, 把它放置到指定位置

或旋转指定角度

- pivot值,算起来稍微复杂一些. 参见代码

//每帧在大图上的位置
int l_iX = Convert.ToInt32(p_subSpriteNode.Attributes["x"].Value);
int l_iY = Convert.ToInt32(p_subSpriteNode.Attributes["y"].Value);
int l_iWidth = Convert.ToInt32(p_subSpriteNode.Attributes["w"].Value);
int l_iHeight = Convert.ToInt32(p_subSpriteNode.Attributes["h"].Value);

//切出的每帧图, 在原始帧上的位置
int l_iSrcOffsetX = Convert.ToInt32(p_subSpriteNode.Attributes["oX"].Value);
int l_iSrcOffsetY = Convert.ToInt32(p_subSpriteNode.Attributes["oY"].Value);
int l_iSrcWidth = Convert.ToInt32 (p_subSpriteNode.Attributes ["oW"].Value);
int l_iSrcHeight = Convert.ToInt32 (p_subSpriteNode.Attributes ["oH"].Value);

//自定义pivot, 保证播放时对齐, 默认(0.5, 0.5)会有抖动
Vector2 l_customPivot = customOffset;
if (l_iWidth > 1 && l_iHeight > 1) {
spriteAlignment = SpriteAlignment.Custom;
l_customPivot.x = 1.0f * (l_iSrcWidth / 2.0f - l_iSrcOffsetX) / l_iWidth;
int l_iSrcOffsetYFromBottom = l_iSrcHeight - (l_iHeight + l_iSrcOffsetY);
l_customPivot.y = 1.0f * (l_iSrcHeight / 2.0f - l_iSrcOffsetYFromBottom) / l_iHeight;
}

l_metaData.name = l_strName;
l_metaData.rect = new Rect (l_iX, p_iWholeImageHeight - (l_iY + l_iHeight), l_iWidth, l_iHeight);
l_metaData.pivot = GetPivotValue (spriteAlignment, l_customPivot);
l_metaData.alignment = (int)spriteAlignment;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: