Unity周边——使用SpriteIlluminator和TexturePacker实现2D动态光照和制作图集

开始

先放上效果图:

这里写图片描述

在Unity(本例中Unity版本为2017.3.1)中实现该功能一共用到了以下工具:

1、SpriteIlluminator:为Sprite添加3D效果并导出法线贴图。本例中使用的版本为1.4.1

2、TexturePacker:打包图集,并导出为Unity所用的格式。本例中使用的版本为4.6.3

*以上两个工具出自同一家公司Code And Web,可以从官网https://www.codeandweb.com上下载。

*注意,如果你使用的是免费版,可能出现某些功能无法使用的情况,比如免费版下SpriteIlluminator的导出法线图的功能就不可使用。请自行破解或购买许可证。

3、TexturePackerImporter:Unity插件,自动处理SpritePacker导出的数据。可以从AssetStore获得。

准备好以上工具后,还需要准备一套序列帧动画素材,这里有一套来自于TexturePackerImporter的资源。

序列帧素材下载

素材预览如下:
这里写图片描述

另外,由于本篇的重点不在深入研究SpriteIlluminator和TexturePacker,所以下面将以尽量少的篇幅来简单介绍下这两个工具的使用。

使用SpriteIlluminator为序列帧添加3D效果

从上面的预览可以看出,这套素材就是一套普通的2D序列帧。这一节我们先使用SpriteIlluminator为其创建一套法线贴图。

1、打开SpriteIlluminator,将序列帧(或者整个文件夹)拖到软件编辑区,图片将以缩略图的形式出现在左边"Sprites"一栏。

2、在Sprites栏按下ctrl+A选中全部图片,这些图片将自动排列在编辑区。编辑区圆形图标表示的是光源。Sprites栏下面有一栏"Global light",它提供了对光源的一些设置。为方便预览,可以把"Auto-rotate light"选上。

这里写图片描述

3、在右侧"Effects"一栏中点击Bevel(斜面),会弹出相关的设置面板,编辑区会即时地给出预览,已经能看出动态光照的效果了。这里使用默认值,点击"Apply"应用设置。

这里写图片描述

4、点击工具栏上"Export normals",根据需要选择路径(不作设置则在原图相同目录下生成)、法线图后缀等设置后点击OK以导出法线图。

这里写图片描述

5、再次打开素材目录,SpriteIlluminator已经为每一副序列帧生成了相应的法线图了。

在Unity中导入TexturePackerImporter插件

打开Unity,我这里使用的版本是2017.3.0,下载的TexturePackerImporter版本是4.6.1。出于演示目的,新建一个2D工程,并导入TexturePackerImporter插件。在Project面板下新建目录"Atlas"用来存放图集(当然,名字可以换作其他的)。

这里写图片描述

使用TexturePacker将序列帧制作成图集

1、打开TexturePacker,在右侧"Settings"下,点击"Choose Data Format",并选中"Unity - Texture2D sprite sheet"以便生成Unity所用的数据格式,最后点击Convert保存应用。

2、与SpriteIlluminator类似,将所有序列帧以及生成的法线图(或者整个文件夹)拖入到编辑区,TexturePacker会自动进行图集的制作,在编辑区可以实时预览到。

3、这时候还需要一些设置,在Settings下,点击Advanced settings进入高级设置。

这里写图片描述

4、主要有三个地方需要设置。一是将Layout一栏中的"Size constraints"设置为"POT(Power of 2)"这样会将图集的尺寸限制为2的n次幂;二是将Normal maps一栏中的"Pack with same layout"勾选,以将序列帧和法线图以相同的布局制成图集;最后将Data一栏中的"Data file"路径设置为我们前面新建的Unity工程中的"Atlas"目录,并起个名字。

这里写图片描述

这里写图片描述

这里写图片描述

5、完成后点击"Publish sprite sheet",TexturePacker将会自动将数据存在刚才设置的目录中。

这里写图片描述

在Unity中的工作

在TexturePacker保存数据至Unity工程时,TexturePackerImporter会自动在Altas目录下生成了4个文件,分别是:

  • Sprites.tpsheet:图集数据文件,记录了子图在图集中的位置、尺寸等信息。

  • Sprites.png:素材图集,点击小箭头可以展开浏览其中包含的子图。已经由TexturePackerImporter自动切片出子图。

  • Sprites:材质文件,默认shader是Standard,可以根据需要更换shader。

  • Sprites_n.png:法线图集。

这里写图片描述

接下来制作动画文件。

这里写图片描述

2、点击Play按钮,即可预览动画效果,此时并没有看见光照效果。原因是我们并没有对物体添加材质,场景中也没有可用的光源。

这里写图片描述

3、在场景中添加一个光源,调整合适的位置、朝向等,我这里使用的是方向光。最后将刚才的材质拖放到游戏物体上。再次运行,可以看见文章开始的动态光照的效果了。

这里写图片描述

获取图集中的子图

对于打包好的图集,有以下三种典型的应用场景:

  • 放在Assets目录下,作为静态资源。

  • 放在Resources目录下,使用Resources来动态加载。

  • 打包成AssetBundle,通过WWW来动态加载。

##放在Assets目录下作为静态资源

这种方式最直接,也最简单。在Project面板下,插件已经自动将Sprites.png切片成精灵,直接拖放到需要的地方即可。

这里写图片描述

放在Resources目录下

在从Resources目录下加载一张Texture2D并获得Sprite的方法可以使用类似下面的方式:

		Texture2D texture2D = Resources.Load (path);
		Sprite sprite = Sprite.Create (texture2D, rect, pivot);

这种方式不需要提前在Unity中对一张图片进行切片,而是使用代码、通过传入Sprite在图片中的尺寸、坐标来进行程序上的切片。

我们固然可以使用这一方法,在Sprites.tpsheet中保存了每一个Sprite的尺寸信息和坐标信息,我们可以编写代码来解析这些信息,并利用这些信息来动态生成Sptire。

这种方法不推荐,我们可以采取更好的方式。

前面说过TexturePackerImporter插件在我们从TexturePacker发布文件到Unity工程时,会自动从Sprite.tpsheet读取数据并对Sprite.png进行切片。在此之后,Sprite.tpsheet已经没有用处了(除非你想自己解析)。我们可以仅将Sprites.png放入Resources目录下,并通过如下代码来获取Sprites图集下所有的子图:

		Sprite[] sprites= Resources.LoadAll<Sprite> ("Sprites");	

如果想要通过子图的名字来索引子图,可以将此sprites转换成名字索引的字典,这里不在赘述。

打包成AssetBundle

打包成AssetBundle这种应用场景类似于放在Resources目录下,不同之处在于,我们需要通过如下方式来获取所有子图。

		Sprite[] sprites = assetBundle.LoadAssetWithSubAssets<Sprite> ("Sprites");
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于unity2d点击切换图片的具体实现方法和完整代码,可以参考以下步骤: 1. 在Unity编辑器中创建一个2D场景,将需要切换的图片导入到场景中,并在层次视图中选择相应的图片。 2. 在场景视图中选择该图片,然后在Inspector视图中找到Sprite Renderer组件,为其添加一个新的Sprite Flip组件。 3. 在Sprite Flip组件的“Sprite Flipping”下拉菜单中选择“SingleClick”选项。 4. 在Sprite Flip组件的“Click Action”下拉菜单中选择“Swap Sprite”选项。 5. 在Sprite Flip组件的“Swap Sprite”选项中为其添加需要切换的图片。 6. 在代码中添加以下代码,实现点击切换图片的功能: ```csharp using UnityEngine; using UnityEngine.EventSystems; public class ClickToSwapSprite : MonoBehaviour, IPointerClickHandler { public Sprite sprite1; public Sprite sprite2; private SpriteRenderer spriteRenderer; private void Start() { spriteRenderer = GetComponent<SpriteRenderer>(); } public void OnPointerClick(PointerEventData eventData) { spriteRenderer.sprite = spriteRenderer.sprite == sprite1 ? sprite2 : sprite1; } } ``` 在这里,我们定义了一个ClickToSwapSprite类,实现了IPointerClickHandler接口来处理点击事件,然后声明了两个Sprite类型的变量sprite1和sprite2,分别存储需要切换的两张图片,同时定义了一个私有的SpriteRenderer类型的变量spriteRenderer,用于获取当前游戏对象的SpriteRenderer组件。 在Start()函数中,我们使用GetComponent()方法获取该游戏对象的SpriteRenderer组件。 最后,在OnPointerClick()函数中,我们利用三目运算符来判断当前显示的图片,如果为sprite1,则将其替换为sprite2,否则替换为sprite1,实现了点击切换图片的功能。 希望能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值