转载请注明:http://blog.csdn.net/xnn2s/article/details/52026853
当动画角色比较多的时候,策划一个一个配状态机和连线非常得麻烦。
实现一个脚本,将fbx动作文件生成状态机;也将模型fbx生成了Prefab,并将之前生成的状态机绑上去。
目前没有做状态之间的连线,状态切换程序自己控制。
做脚本的时候,参考了网上文章,然后,我以商业项目的要求实现了这个脚本。
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.Animations;
public class BuildingEditor : MonoBehaviour
{
static string ReadAnimationPath = Application.dataPath + "/Art/3D/Character";
static string GenerateAnimatorPath = "Assets/Resources/Prefabs/Character/Animator";
static string GeneratePrefabPath = "Assets/Resources/Prefabs/Character";
[MenuItem("Tools/Generate Animator Prefabs")]
public static void GenerateAnimatorPrefab()
{
List<string> files = new List<string>();
FindFile(ReadAnimationPath, "*.fbx", files);
Dictionary<string, List<string>> classifyFiles = new Dictionary<string, List<string>>();
ClassifyFiles(files, classifyFiles);
GenerateAnimatorPrefabs(classifyFiles);
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
}
static void GenerateAnimatorPrefabs(Dictionary<string, List<string>> classifyFiles)
{
foreach (KeyValuePair<string, List<string>> kvp in classifyFiles)
{
string controllerPath = kvp.Key;
string name = string.Empty;
int startIdx = controllerPath.LastIndexOf('\\');
int pos = controllerPath.IndexOf('.');
if (startIdx != -1 && pos != -1)
{
name = controllerPath.Substring(startIdx, pos - startIdx);
controllerPath = name;
controllerPath += ".controller";
controllerPath = GenerateAnimatorPath + controllerPath;
Debug.Log(controllerPath);
GenerateAnimators(controllerPath, kvp.Value);
}
string fbxPath = kvp.Key;
fbxPath = fbxPath.Substring(fbxPath.IndexOf("Assets\\"));
GeneratePrefabs(name, fbxPath, controllerPath);
}
}
static AnimatorController GenerateAnimators(string file, List<string> fbxs)
{
AnimatorController animator = AnimatorController.CreateAnimatorControllerAtPath(file);
AnimatorControllerLayer layer = animator.layers[0];
for (int i = 0; i < fbxs.Count; i++)
{
string fbx = fbxs[i];
fbx = fbx.Substring(fbx.IndexOf("Assets\\"));
Debug.Log(fbx);
AnimationClip clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(fbx);
AnimatorStateMachine stateMachine = layer.stateMachine;
AnimatorState state = stateMachine.AddState(clip.name, new Vector3(250, 52 * i, 0));
state.motion = clip;
int startIdx = fbx.IndexOf('@');
if (fbx.Substring(startIdx + 1) == "idel_fight.FBX")
stateMachine.defaultState = state;
}
// AnimationClip clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(DataPathToAssetPath(file1[i].FullName));
// if (clip.name == RUN_ANIMATION)
// {
// AnimatorState state = layer.stateMachine.AddState(clip.name, new Vector3(250, 0, 0));
// state.motion = clip;
// //添加转换状态,true代表激活退出状态
// state.AddTransition(layer.stateMachine.defaultState, true);
// // 播完动画才能退出
// state.transitions[0].exitTime = 1F;
// state.transitions[0].duration = 0;
// }
return animator;
}
static void GeneratePrefabs(string name, string fbxPath, string controllerPath)
{
GameObject origalGo = AssetDatabase.LoadAssetAtPath<GameObject>(fbxPath);
GameObject go = Instantiate(origalGo);
EditorUtility.SetDirty(go);
Selection.activeObject = go;
if (!go.GetComponent<Animator>())
go.AddComponent<Animator>();
Animator animator = go.GetComponent<Animator>();
animator.runtimeAnimatorController = AssetDatabase.LoadAssetAtPath<RuntimeAnimatorController>(controllerPath);
animator.applyRootMotion = true;
name = name.Replace('\\', '/');
string prefabPath = GeneratePrefabPath + name + ".prefab";
PrefabUtility.CreatePrefab(prefabPath, go);
// Editor模式下只能用这个
DestroyImmediate(go);
}
static void FindFile(string path, string searchPattern, List<string> files)
{
path += "\\";
DirectoryInfo dir = new DirectoryInfo(path);
foreach (DirectoryInfo di in dir.GetDirectories())
FindFile(di.ToString(), searchPattern, files);
foreach (FileInfo fi in dir.GetFiles(searchPattern))
files.Add(fi.ToString());
}
static void ClassifyFiles(List<string> files, Dictionary<string, List<string>> classifyFiles)
{
for (int i = 0; i < files.Count; i++)
{
string file = files[i];
int pos = file.IndexOf('@');
string classifyName;
if (pos == -1)
classifyName = file;
else
{
classifyName = file.Substring(0, file.IndexOf('@'));
classifyName += ".FBX";
}
List<string> classifyFilesVal;
if (classifyFiles.ContainsKey(classifyName))
{
classifyFilesVal = classifyFiles[classifyName];
classifyFilesVal.Add(file);
}
else
{
classifyFilesVal = new List<string>();
classifyFiles.Add(classifyName, classifyFilesVal);
}
}
}
}
u3d5.3 版本,注意两个输出要自己建一下。