从gif到unity sprite——批量转换gif、批量导入texture packer图集为sprite、批量生成sprite预制体

背景是我有几百个角色gif资源,每个都有:站立、攻击、技能攻击的gif,我想用此资源作2d unity游戏,因此第一关就是如何把gif转成unity动画

GIF 转 PNG —— http://blog.csdn.net/leinchu/article/details/24806433 ,不再赘述了。

之后是批量gif用tp打包,我用php写了一个脚本遍历目录,下的gif把他们重命名并每个角色建立一个文件夹,把它的所有动作的png序列移动到他自己的目录去,再用tp打包:

上php代码,因为我是分布做的,你根据自己的情况改改吧

<?php
$arr = scandir(dirname(__FILE__));

$count = 0;
foreach($arr as $f)
{
	if($f==‘.‘||$f==‘..‘ ||!is_dir($f) || in_array($f,array(‘LAsset‘,‘deal_name.php‘))) continue;
	$strs = explode("_",$f);
	$pre = $strs[0];
	$id = str_replace(‘.png‘,‘‘,$strs[1]);
	$num = intval(preg_replace("/[^\d]/","",$strs[2]));

	$folder = ‘bb_‘.$id;
	if(!file_exists($folder)) mkdir($folder);

	if($num<1) $num =1;
	$cmd = "move ".$f.‘ ‘.$folder.‘/‘.$pre.‘_‘.$num.‘.png‘;
	exec($cmd);
	$cmd = ‘C:\TexturePacker\bin\TexturePacker --trim-sprite-names  --inner-padding 1 --disable-rotation ‘.$f.‘ --data ‘.$f.‘/‘.$f.‘.txt --format unity --sheet LAsset/‘.$f.‘.png --max-width 8192 --max-height 8192‘;
	exec($cmd);
	$txt = file_get_contents($f.‘/‘.$f.‘.txt‘);
	$arr =(array) json_decode($txt);

	$a = array();
	$h = $arr[‘meta‘]->size->h;
	$arr = (array) $arr[‘frames‘];

	//var_dump($arr);die();
	foreach($arr as $name=>$fr){
		$a[] = $name.‘,‘.$fr->frame->x.‘,‘.$fr->frame->y.‘,‘.$fr->frame->w.‘,‘.$fr->frame->h
		.‘,‘.$fr->spriteSourceSize->x//用于计算Pivot
		.‘,‘.$fr->spriteSourceSize->y
		.‘,‘.$fr->spriteSourceSize->w
		.‘,‘.$fr->spriteSourceSize->h
		.‘,‘.$h//tp的原点在左上角,unity的在右下角,需要用图集高度来转换
		.‘,‘.$fr->sourceSize->w
		.‘,‘.$fr->sourceSize->h
		;
	}
	file_put_contents(‘LAsset/‘.$f.‘.txt‘,implode("\r\n", $a));
	echo $f." OK\n";
	//if($count++<5) echo $cmd."\n";else break;
}

之后是自动把png图集转换成sprite集合,我写了脚本,你只要把这个脚本放进你的项目就可以了,然后再asset目录下建立个目录LAsset,右键这个目录把png图集导入进来,就会自动转成sprite集合了

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using System.IO;

/*
Your origin picture diretory should be like:
/folder
/folder/LAsset/hero_1
/folder/LAsset/hero_1/spriteAltas.png
/folder/LAsset/hero_1/spriteAltas.txt
/folder/LAsset/hero_2/spriteAltas.png
/folder/LAsset/hero_2/spriteAltas.txt

spriteAltas.txt should be in format of "stand_1,x,y,width,height\r\nstand_2,x,y,width,height\r\nattack_1,x,y,width,height\r\nattack_2,x,y,width,height\r\nattack_3,x,y,width,height"
and finally you will got two prefabs(hero_1, hero_2) both of them has a sprite which has five members(sprites): stand_1,stand_2,attack_1,attack_2,attack_3
 */
public class LAssetPostprocessor : AssetPostprocessor
{
		void OnPostprocessAllAssets (
		string[] importedAssets,
		string[] deletedAssets,
		string[] movedAssets,
		string[] movedFromAssetPaths)
		{
				Debug.Log ("====================== *OnPostprocessAllAssets* ===================");
				foreach (string str in importedAssets) {
						Debug.Log ("Reimported Asset: " + str);
				}

				foreach (string str in deletedAssets) {
						Debug.Log ("Deleted Asset: " + str);
				}

				for (int i=0; i < movedAssets.Length; i++) {
						Debug.Log ("Moved Asset: " + movedAssets [i] + " from: " + movedFromAssetPaths [i]);
				}
		}

		void OnProcessSprite ()
		{
				Utils.log ("++++++++++++++++++++ OnProcessSprite ++++++++++++++++++", 1);
		}

		public static string autoPathMark = "Pets";//
		private string spriteLoadFrom = "C:/D/2014/poke/img/images/bb/test/Result/LAsset/";
		private int padding = 1;

		void OnPreprocessTexture ()
		{
				Utils.log ("OnPreprocessTexture: " + assetPath);
				if (Path.GetExtension (assetPath) == ".png" && assetPath.IndexOf (autoPathMark) != -1) {
						string[] path;
						if (assetPath.IndexOf ("/") != -1)
								path = assetPath.Substring (assetPath.IndexOf (autoPathMark) + autoPathMark.Length + 1).Split (new string[]{"/"}, StringSplitOptions.RemoveEmptyEntries);
						else
								path = assetPath.Substring (assetPath.IndexOf (autoPathMark) + autoPathMark.Length + 1).Split (new string[]{"\\"}, StringSplitOptions.RemoveEmptyEntries);
						string spriteName = path [0].Replace (".png", "");

						string atlasPath = spriteLoadFrom + spriteName + ".txt";
						Utils.log ("Auto make sprite: " + assetPath + ", atlasPath=" + atlasPath);

						if (File.Exists (atlasPath)) {
								TextureImporter importer = assetImporter as TextureImporter;

								importer.spriteImportMode = SpriteImportMode.Multiple;
								importer.spritePixelsToUnits = 100;
								importer.spritePackingTag = spriteName;
								spriteSheetRow[] spriteSheet = spriteSheetConfigReader.getSpriteSheet (atlasPath);
								int count = spriteSheet.Length;

								Utils.log ("------------------------------------> Frame count: " + count);
								spriteSheetRow row;
								List<SpriteMetaData> spriteMetaData = new List<SpriteMetaData> ();
								for (int i=0; i<count; i++) {
										row = spriteSheet [i];
										string n = row.name;
										int x = row.x;
										int y = row.y;
										int w = row.w;
										int h = row.h;

										int height = row.height;

										//Utils.log ("==>>    x=" + x + ", y=" + y + ", w=" + w + ", h=" + h + ", height=" + height);
										SpriteMetaData metaData = new SpriteMetaData ();
										// According to Unity docs, Center = 0, Custom = 9
										metaData.alignment = 9;
										metaData.name = n;

										metaData.pivot = Vector2.zero;
										//metaData.pivot = new Vector2 ((row.ox + row.ow - row.sw / 2.0f) / (float)w, (row.oy + row.oh - row.sh / 2.0f) / (float)h);// Vector2 (0.5f, 0.5f);
										metaData.rect = new Rect (x, height - h - y + padding, w, h);

										spriteMetaData.Add (metaData);
								}

								importer.spritesheet = spriteMetaData.ToArray ();
								importer.name = spriteName;
						}
				}
		}
}

public struct spriteSheetRow
{
		public string name;
		public int x;
		public int y;
		public int w;
		public int h;
		public int ox;
		public int oy;
		public int ow;
		public int oh;
		public int height;//图集的高度
		public int sw;//当前帧的没有裁切的宽度
		public int sh;//当前帧的没有裁切的高度
}

public class spriteSheetConfigReader
{

		public static spriteSheetRow[] getSpriteSheet (string configFilePath)
		{
				//Get content of the config file, config file is suppose to in format of "name,x,y,width,height\r\nname,x,y,width,height\r\nname,x,y,width,height"
				string[] config_strs = FileUtils.getInstance ().ReadFile (configFilePath, "").Split (new string[] {
						"\r\n"
				}, StringSplitOptions.RemoveEmptyEntries);

				int len = config_strs.Length;
				spriteSheetRow[] arr = new spriteSheetRow[len];
				for (int i=0; i<len; i++) {
						//for debug message, you can delete it
						ConfigLoader.log_head = configFilePath + " > row " + i;

						string[] tmp = config_strs [i].Split (new string[]{","}, StringSplitOptions.RemoveEmptyEntries);
						spriteSheetRow row;
						row.name = tmp [0];
						row.x = Utils.parseInt (tmp [1]);
						row.y = Utils.parseInt (tmp [2]);
						row.w = Utils.parseInt (tmp [3]);
						row.h = Utils.parseInt (tmp [4]);

						row.ox = Utils.parseInt (tmp [5]);
						row.oy = Utils.parseInt (tmp [6]);
						row.ow = Utils.parseInt (tmp [7]);
						row.oh = Utils.parseInt (tmp [8]);

						row.height = Utils.parseInt (tmp [9]);
						row.sw = Utils.parseInt (tmp [10]);
						row.sh = Utils.parseInt (tmp [11]);

						arr [i] = row;

				}
				return arr;
		}
}

因为在导入过程中sprite没有生成,也没有生成后再调用的方法,所以只能再通过一个菜单来批量转换为prefab,把下面的脚本放到你的项目里面,在unity里面选中Asset/LAsset目录,点击菜单Assets/+> Build Prefabs From Selection...预制体就会被打包到Resources下(具体自己改路径吧)

using UnityEngine;
using UnityEditor;
using System.IO;
using System;
using System.Collections;
using System.Collections.Generic;

public class LExportPrefabs
{
		private static string[] state_type = new string[]{"stand","attack","skill"};

		[MenuItem("Assets/+> Build Prefabs From Selection...")]
		static void LExportResource ()
		{
				//List<string> pathList = new List<string> ();
				UnityEngine.Object[] objs = Selection.GetFiltered (typeof(UnityEngine.Object), SelectionMode.DeepAssets);
				foreach (UnityEngine.Object _obj in objs) {
						string path = AssetDatabase.GetAssetPath (_obj);
						Utils.log (path);
						if (Path.GetExtension (path) == ".png" && path.IndexOf (LAssetPostprocessor.autoPathMark) != -1) {
								string filename = Path.GetFileName (path);
								string spriteName = filename.Replace (".png", "");
								//pathList.Add (path);
								Utils.log (path + " creating prefab for " + spriteName + "...");
								GameObject obj = new GameObject (spriteName);
								obj.AddComponent<SpriteRenderer> ();
								TurnModeRPGAnimator animator = obj.AddComponent<TurnModeRPGAnimator> ();

								List<Dictionary<int, int>> frameOrderOfState = new List<Dictionary<int, int>> ();
								frameOrderOfState.Add (new Dictionary<int, int> ());
								frameOrderOfState.Add (new Dictionary<int, int> ());
								frameOrderOfState.Add (new Dictionary<int, int> ());

								UnityEngine.Object[] arr = AssetDatabase.LoadAllAssetsAtPath (path);
								int len = arr.Length;

								//List<Sprite> sprites = new List<Sprite> ();
								Utils.log ("length: " + len);
								for (int i=0; i<len; i++)
										if (arr [i] is Sprite) {
												for (int j=0; j<3; j++)
														if (arr [i].name.IndexOf (state_type [j]) != -1) {
																frameOrderOfState [j].Add (Utils.parseInt (arr [i].name.Replace (state_type [j] + "_", "")), animator.sprites.Count);
																break;
														}
												animator.sprites.Add (arr [i] as Sprite);
										}
								int idx = 0;
								foreach (Dictionary<int, int> item in frameOrderOfState) {

										int[] arrFrames = new int[item.Count];
										for (int i=0; i<item.Count; i++)
												arrFrames [i] = item [i+1];

										if (idx == 0)
												animator.standFrames = arrFrames;
										else if (idx == 1)
												animator.attackFrames = arrFrames;
										else
												animator.skillFrames = arrFrames;

										idx++;
								}
				animator.dics.Add(1,2);
				animator.dics.Add(2,317);
					PrefabUtility.CreatePrefab ("Assets/Resources/Pets/" + spriteName + ".prefab", obj);
								GameObject.DestroyImmediate (obj);
								Utils.log ("OK");
						}

				}  

		}
}

预制体使用:

UnityEngine.GameObject _obj = Resources.Load ("Pets/bb_" + id) as GameObject;
				if (_obj != null) {
						Utils.log ("Resources loaded OK");
				} else
						Utils.log ("Resources failt to load");
				Instantiate (_obj, new Vector3 (id % 3, 0, 0), new Quaternion ());

我的QQ群:

PHPer&页游&Mobile&U3D 2D,群号:95303036

加群除了提问之外,请记得帮助别人,谢谢。

从gif到unity sprite——批量转换gif、批量导入texture packer图集为sprite、批量生成sprite预制体

时间: 2024-11-08 07:39:55

从gif到unity sprite——批量转换gif、批量导入texture packer图集为sprite、批量生成sprite预制体的相关文章

关于Unity中stretch的分开使用、预制体、Scroll View的UI节点

一.上次讲的菊花的四个花瓣,只讲了四个花瓣和在一起的时候的作用,现在是分开的菊花的四个花瓣的作用 1.创建一个Canvas2.对Canvas进行初始化3.创建一个Image的UI节点作为Canvas的子节点,名字叫bg.4.再创建一个GameObject的空节点作为Canvas的子节点.5.在GameObject下面创建一个叫icon的Image类型的UI子节点6.把icon的颜色改为红色便于观察,大小改为300X300点击左上角的stretch,图案选择最右下角的四个花瓣对应四个角的状态,7.

【游戏开发】Excel表格批量转换成CSV的小工具

一.前言 在工作的过程中,我们有时可能会面临将Excel表格转换成CSV格式文件的需求.这尤其在游戏开发中体现的最为明显,策划的数据文档大多是一些Excel表格,且不说这些表格在游戏中读取的速度,但就论占用内存来说,同样的数据量Excel表格所占用的内存要远远大于CSV,因此将Excel转换成CSV势在必行.如果单单转换一个Excel表格还好,直接另存为就搞定的,但是如何将一个文件下的N个Execl表格转成CSV呢?今天马三就来和大家一起用Python撸一个Excel表格批量转换CSV的小工具—

【游戏开发】Excel表格批量转换成lua的转表工具

一.简介 在上篇博客<[游戏开发]Excel表格批量转换成CSV的小工具> 中,我们介绍了如何将策划提供的Excel表格转换为轻便的CSV文件供开发人员使用.实际在Unity开发中,很多游戏都是使用Lua语言进行开发的.如果要用Lua直接读取CSV文件的话,又要写个对应的CSV解析类,不方便的同时还会影响一些加载速度,牺牲游戏性能.因此我们可以直接将Excel表格转换为lua文件,这样就可以高效.方便地在Lua中使用策划配置的数据了.在本篇博客中,马三将会和大家一起,用C#语言实现一个Exce

在windows下如何批量转换pvr,ccz为png或jpg

这是一个很常见的功能,但是找了全网,居然找不到,于是借鉴别人的批处理文件,改了下,就可以把整个目录的全部一次批量转换. 将这个bat文件暂定为,myConvert.bat,执行时就把这个bat文件放到要转换的目录,然后双击bat,就可以啦.下面把bat文件贴出来: rem path " "里面内容替换为TexturePacker的安装路径,将bat文件放在图片文件夹直接运行就可以了 @ech off path %path%;"c:\TexturePacker\bin"

API地图坐标转化(批量转换坐标)

```html 批量转换坐标(据说有50次/秒的限制哦) 谷歌地图 鼠标点击的谷歌坐标是: 百度地图 鼠标点击的百度坐标是:() ``` ```javascript // (function(){ function loadscript(xyUrl, callback){ var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type =

想效率高些?cad怎么样批量转换成pdf

遇到CAD文件,很多人都会犯愁,因为打不开,因此很多小伙伴都会将CAD文件转换成PDF文件.那么如果面对大量的CAD文件,我们该如何将CAD文件批量转换成PDF呢?这里教大家CAD怎么样批量转换成PDF比较方便. 第一步,下载迅捷CAD编辑器 打开浏览器,输入"迅捷CAD编辑器"(http://cad.xjpdf.com)搜索软件,找到软件下载资源后,请点击立即下载,下载软件安装包,然后按照步骤安装软件即可. 第二步,调出批处理功能 借助于迅捷CAD编辑器将CAD批量转换成PDF文件,

Linux下将UTF8编码批量转换成GB2312编码的方法

Linux下将UTF8编码批量转换成GB2312编码的方法 在sqlplus中导入UTF8编码的sql脚本就会出现乱码错误,这时就需要将UTF8编码转换成GB2312编码,下面为大家介绍下在Linux下如何进行转换 UTF8编码和GB2312编码是有区别的,在sqlplus中导入UTF8编码的sql脚本就会出现乱码错误,这时就需要将UTF8编码转换 成GB2312编码,可是一个个的转换十分麻烦,下面小编就教你如何在Linux下将UTF8编码批量转换成GB2312编码. 背景 本人在使用oracl

[Linux] 批量转换整个目录下的文件编码为UTF-8;

[Linux] 批量转换整个目录下的文件编码为UTF-8: #!/bin/bash - #===============================================================================# #          FILE: conv.sh#  #         USAGE: ./conv.sh #  #   DESCRIPTION: 一个支持把整个目录递归转换GB2312为UTF-8的脚本: #  #       OPTIONS: 

convert图像格式批量转换

问题:利用GMT绘制生成了eps格式的图像,为了将图像插入到word中,且保持较高的分辨率,利用convert进行图像格式转换,将eps转换成tiff格式. code: for i in *.psdoecho $iname=`basename $i .ps`convert $i ${name}.tiffdone 出现错误: tran.sh: line 2: syntax error near unexpected token `$'do\r'''ran.sh: line 2: `do解决方法: