您的位置:首页 > 其它

u3d fbx动画模型生成Animator Controller和Prefab工具脚本

2016-07-25 19:46 507 查看
转载请注明: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 版本,注意两个输出要自己建一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: