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

转载请注明: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 版本,注意两个输出要自己建一下。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值