[Unity2d系列教程] 006.Unity如何根據圖片自動生成Animator

Unity製做2D產品的時候,咱們在製做動畫的時候,要不斷的生成Animation,Animator等等資源,若是動畫一多的話,就變得麻煩。因爲Unity是支持插件開發的,咱們能夠添加一個Editor,而後把美術的動畫圖片放在指定的位置。oop

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

public class BuildAnimation : Editor 
{
	
	//生成出的Prefab的路徑
	private static string PrefabPath = "Assets/Resources/Prefabs";
	//生成出的AnimationController的路徑
	private static string AnimationControllerPath = "Assets/AnimationController";
	//生成出的Animation的路徑
	private static string AnimationPath = "Assets/Animation";
	//美術給的原始圖片路徑
	private static string ImagePath = Application.dataPath +"/Raw";
	
	[MenuItem("Build/BuildAnimaiton")]
	static void BuildAniamtion() 
	{
		DirectoryInfo raw = new DirectoryInfo (ImagePath);		
		foreach (DirectoryInfo dictorys in raw.GetDirectories()) 
		{
			List<AnimationClip> clips = new List<AnimationClip>();
			foreach (DirectoryInfo dictoryAnimations in dictorys.GetDirectories()) 
			{
				//每一個文件夾就是一組幀動畫,這裏把每一個文件夾下的全部圖片生成出一個動畫文件
				clips.Add(BuildAnimationClip(dictoryAnimations));
			}
			//把全部的動畫文件生成在一個AnimationController裏
			AnimatorController controller =	BuildAnimationController(clips,dictorys.Name);
			//最後生成程序用的Prefab文件
			BuildPrefab(dictorys,controller);
		}	
	}
	
	
	static AnimationClip BuildAnimationClip(DirectoryInfo dictorys)
	{
		string animationName = dictorys.Name;
		//查找全部圖片,由於我找的測試動畫是.jpg 
		FileInfo []images  = dictorys.GetFiles("*.png");
		AnimationClip clip = new AnimationClip();
		 //AnimationUtility.SetAnimationType(clip,ModelImporterAnimationType.Generic);
		EditorCurveBinding curveBinding = new EditorCurveBinding();
		curveBinding.type = typeof(SpriteRenderer);
		curveBinding.path="";
		curveBinding.propertyName = "m_Sprite";
		ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Length];
		//動畫長度是按秒爲單位,1/10就表示1秒切10張圖片,根據項目的狀況能夠本身調節
		float frameTime = 1/10f;
		for(int i =0; i< images.Length; i++){
			Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images[i].FullName));
			keyFrames[i] =   new ObjectReferenceKeyframe ();
			keyFrames[i].time = frameTime *i;
			keyFrames[i].value = sprite;
		}
		//動畫幀率,30比較合適
		clip.frameRate = 30;
		
		//有些動畫我但願天生它就動畫循環
		if(animationName.IndexOf("idle") >=0 )
		{
			//設置idle文件爲循環動畫
			SerializedObject serializedClip = new SerializedObject(clip);
			AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));
			clipSettings.loopTime = true;
			serializedClip.ApplyModifiedProperties();
		}
		string parentName = System.IO.Directory.GetParent(dictorys.FullName).Name;
		System.IO.Directory.CreateDirectory(AnimationPath +"/"+parentName);
		AnimationUtility.SetObjectReferenceCurve(clip,curveBinding,keyFrames);
		AssetDatabase.CreateAsset(clip,AnimationPath +"/"+parentName +"/" +animationName+".anim");
		AssetDatabase.SaveAssets();
		return clip;
	}
	
	static AnimatorController BuildAnimationController(List<AnimationClip> clips ,string name)
	{
		AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(AnimationControllerPath +"/"+name+".controller");
		AnimatorControllerLayer layer = animatorController.layers[0];
		AnimatorStateMachine sm = layer.stateMachine;
		foreach(AnimationClip newClip in clips)
		{
			//AnimatorStateMachine machine = sm.AddStateMachine(newClip.name);
			AnimatorState state = sm.AddState(newClip.name);
			state.motion = newClip;
			//AnimatorStateTransition trans = sm.AddAnyStateTransition(state);
			if(newClip.name == "idle"){
				sm.defaultState = state;
			}
			//sm.AddEntryTransition(machine);
			//sm.AddStateMachineExitTransition(machine);
			//trans.RemoveCondition(0);
		}
		AssetDatabase.SaveAssets();
		return animatorController;
	}
	
	static void BuildPrefab(DirectoryInfo dictorys,AnimatorController animatorCountorller)
	{
		//生成Prefab 添加一張預覽用的Sprite
		FileInfo images  = dictorys.GetDirectories()[0].GetFiles("*.png")[0];
		GameObject go = new GameObject();
		go.name = dictorys.Name;
		SpriteRenderer spriteRender =go.AddComponent<SpriteRenderer>();
		spriteRender.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images.FullName));
		Animator animator = go.AddComponent<Animator>();
		animator.runtimeAnimatorController = animatorCountorller;
		PrefabUtility.CreatePrefab(PrefabPath+"/"+go.name+".prefab",go);
		DestroyImmediate(go);
	}
	
	
	public static string DataPathToAssetPath(string path)
	{
		if (Application.platform == RuntimePlatform.WindowsEditor)
			return path.Substring(path.IndexOf("Assets\\"));
		else
			return path.Substring(path.IndexOf("Assets/"));
	}
	
	
	class AnimationClipSettings
	{
		SerializedProperty m_Property;
		
		private SerializedProperty Get (string property) { return m_Property.FindPropertyRelative(property); }
		
		public AnimationClipSettings(SerializedProperty prop) { m_Property = prop; }
		
		public float startTime   { get { return Get("m_StartTime").floatValue; } set { Get("m_StartTime").floatValue = value; } }
		public float stopTime	{ get { return Get("m_StopTime").floatValue; }  set { Get("m_StopTime").floatValue = value; } }
		public float orientationOffsetY { get { return Get("m_OrientationOffsetY").floatValue; } set { Get("m_OrientationOffsetY").floatValue = value; } }
		public float level { get { return Get("m_Level").floatValue; } set { Get("m_Level").floatValue = value; } }
		public float cycleOffset { get { return Get("m_CycleOffset").floatValue; } set { Get("m_CycleOffset").floatValue = value; } }
		
		public bool loopTime { get { return Get("m_LoopTime").boolValue; } set { Get("m_LoopTime").boolValue = value; } }
		public bool loopBlend { get { return Get("m_LoopBlend").boolValue; } set { Get("m_LoopBlend").boolValue = value; } }
		public bool loopBlendOrientation { get { return Get("m_LoopBlendOrientation").boolValue; } set { Get("m_LoopBlendOrientation").boolValue = value; } }
		public bool loopBlendPositionY { get { return Get("m_LoopBlendPositionY").boolValue; } set { Get("m_LoopBlendPositionY").boolValue = value; } }
		public bool loopBlendPositionXZ { get { return Get("m_LoopBlendPositionXZ").boolValue; } set { Get("m_LoopBlendPositionXZ").boolValue = value; } }
		public bool keepOriginalOrientation { get { return Get("m_KeepOriginalOrientation").boolValue; } set { Get("m_KeepOriginalOrientation").boolValue = value; } }
		public bool keepOriginalPositionY { get { return Get("m_KeepOriginalPositionY").boolValue; } set { Get("m_KeepOriginalPositionY").boolValue = value; } }
		public bool keepOriginalPositionXZ { get { return Get("m_KeepOriginalPositionXZ").boolValue; } set { Get("m_KeepOriginalPositionXZ").boolValue = value; } }
		public bool heightFromFeet { get { return Get("m_HeightFromFeet").boolValue; } set { Get("m_HeightFromFeet").boolValue = value; } }
		public bool mirror { get { return Get("m_Mirror").boolValue; } set { Get("m_Mirror").boolValue = value; } }
	}
	
}

 以上代碼支持Unity5.0以上。測試

代碼拷貝進去本身試試就知道了,很是方便動畫

相關文章
相關標籤/搜索