标签:des blog class code tar ext
背景是我有几百个角色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预制体,布布扣,bubuko.com
从gif到unity sprite——批量转换gif、批量导入texture packer图集为sprite、批量生成sprite预制体
标签:des blog class code tar ext
原文地址:http://blog.csdn.net/leinchu/article/details/25041047