批量创建预制体添加动画

 公司有需求,把暂时有的四十多个模型,都添加一个animator组件并且给添加动画状态控制,并且打出ab包。这就很烦了,于是花了一个下午把工具写完,最近也在捣鼓editor工具,公司加密软件没带不出demo来,思路还在,回家复盘,并且加上窗口!
复制代码
 private static string PrefabEndsWith = ".prefab";
    /// <summary>
    /// 创建预制体
    /// </summary>
    /// <param name="选择的物体"></param>
    /// <param name="预制体存放路径"></param>
    /// <param name="预制体父物体路径"></param>
    public static void MyCreationPrefab(GameObject[] objs, string rootPath, string parent)
    {
        try
        {
            string path = rootPath + parent + "/";
            if (!Directory.Exists(path)) Directory.CreateDirectory(path);
            for (int i = 0; i < objs.Length; i++)
            {
                EditorUtility.DisplayProgressBar("制作预制体", "名字:" + objs[i].name, i * 1.0f / objs.Length);

#if UNITY_2018
                GameObject TempPrefab =  PrefabUtility.CreatePrefab(path + name + ".prefab", objs[i]);
#elif UNITY_2019
                GameObject TempPrefab = PrefabUtility.SaveAsPrefabAsset((GameObject)PrefabUtility.InstantiatePrefab(objs[i]), path + GetPrefabName(objs[i].name) + PrefabEndsWith);
#endif
            }
            EditorUtility.ClearProgressBar();
        }
        catch (System.Exception e)
        {
            Debug.LogError($"创建预制体失败!{e}");
            EditorUtility.ClearProgressBar();
        }
    }
    /// <summary>
    /// 创建预制体重载
    /// </summary>
    /// <param name="modelPath"></param>
    /// <param name="paefabRoot"></param>
    /// <param name="是否给模型添加动画状态机"></param>
    /// <param name="动画状态机存放地址"></param>
    public static void MyCreationPrefab(List<string> modelPath, string paefabRoot, bool setAnim, string animPath)
    {
        try
        {
            for (int i = 0; i < modelPath.Count; i++)
            {
                if (modelPath[i] == "") continue;
                string path = paefabRoot + PathToPrefabParent(modelPath[i]) + "/";
                if (!Directory.Exists(path)) Directory.CreateDirectory(path);
                List<string> mPath = GetModels(modelPath[i]);
                for (int j = 0; j < mPath.Count; j++)
                {
                    EditorUtility.DisplayProgressBar("制作预制体", "模型路径:" + mPath[j], j * 1.0f / mPath.Count);
#if UNITY_2018
            PrefabUtility.CreatePrefab(path + name + ".prefab", objs[i]);
#elif UNITY_2019
                    GameObject TempPrefab = PrefabUtility.SaveAsPrefabAsset((GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath<GameObject>(mPath[j])), path + PathToPrefabName(mPath[j]) + PrefabEndsWith);
#endif
                    if (setAnim)
                    {
                        SetAnimatorController(TempPrefab, mPath[j], animPath, PathToPrefabName(mPath[j]));
                    }
                }
                EditorUtility.ClearProgressBar();
            }

        }
        catch (System.Exception e)
        {
            Debug.LogError($"创建预制体失败!{e}");
            EditorUtility.ClearProgressBar();
        }
    }
    /// <summary>
    /// 获取模型的名字
    /// </summary>
    /// <param name="pathList"></param>
    /// <returns></returns>
    public static List<string> GetModels(string pathList)
    {
        try
        {
            List<string> modelPath = new List<string>();
            string[] allStr = AssetDatabase.FindAssets("t:model", new string[] { pathList });
            for (int i = 0; i < allStr.Length; i++)
            {
                string path = AssetDatabase.GUIDToAssetPath(allStr[i]);

                if (allStr.Length > 100)
                {
                    EditorUtility.DisplayProgressBar("查找模型", "ModelPath:" + path, i * 1.0f / allStr.Length);
                }
                modelPath.Add(path);
            }
            EditorUtility.ClearProgressBar();
            return modelPath;

        }
        catch (System.Exception e)
        {
            EditorUtility.ClearProgressBar();
            Debug.LogError($"查找模型失败{e}!");
            return null;

        }

    }
    /// <summary>
    /// 给预制体添加动画
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="modelPath"></param>
    /// <param name="animatorControllerPath"></param>
    /// <param name="name"></param>
    public static void SetAnimatorController(GameObject obj, string modelPath, string animatorControllerPath, string name)
    {
        Animator anim = obj.GetComponent<Animator>();
        if (anim)
        {
            AnimatorController controller = AnimatorController.CreateAnimatorControllerAtPath(animatorControllerPath + name + ".controller");
            AnimatorController.SetAnimatorController(anim, controller);
            AnimatorControllerLayer layer = controller.layers[0];
            AnimatorStateMachine machine = layer.stateMachine;

            controller.AddParameter("e", AnimatorControllerParameterType.Bool);

            AnimatorState IdleState = machine.AddState("Idle", new Vector3(300, 0, 0));
            machine.defaultState = IdleState;
            AnimatorState behaviorState = machine.AddState("behavior", new Vector3(550, 0, 0));
            behaviorState.motion = GetAnimationClip(modelPath);

            AnimatorStateTransition behaviorTrue = IdleState.AddTransition(behaviorState);
            behaviorTrue.AddCondition(AnimatorConditionMode.If, 1f, "e");
            AnimatorStateTransition behaviorFlas = behaviorState.AddTransition(IdleState);
            behaviorFlas.AddCondition(AnimatorConditionMode.IfNot, 1F, "e");
        }
        else
        {
            Debug.Log(obj.name + "没有挂载动画状态机组件");
        }
    }

    /// <summary>
    /// 获取动画片段
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static AnimationClip GetAnimationClip(string path)
    {
        Object[] objects = AssetDatabase.LoadAllAssetsAtPath(path);
        for (int m = 0; m < objects.Length; m++)
        {
            if (objects[m].GetType() == typeof(AnimationClip))
            {
                AnimationClip clip = (AnimationClip)objects[m];
                return clip;
            }
        }
        return null;
    }
    /// <summary>
    /// 获取动画片段
    /// </summary>
    /// <param name="go"></param>
    /// <returns></returns>
    public static AnimationClip GetAnimationClip(GameObject go)
    {
        return go.GetComponent<Animation>().clip;
    }

    /// <summary>
    /// 给模型名字返回预制的名字
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    static string GetPrefabName(string name)
    {
        return name.Replace("_", "");
    }
    /// <summary>
    /// 得到模型的名字
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    static string PathToPrefabName(string path)
    {
        string[] str = path.Split('/');
        string result = str[str.Length - 1];
        result = result.Replace("_", "");
        result = result.Replace(".fbx", "");
        return result;
    }
    /// <summary>
    /// 得到模型父物体名字  "Assets/Model"
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    static string PathToPrefabParent(string path)
    {
        string[] str = path.Split('/');
        string result = str[str.Length - 1];
        return result;
    }
复制代码
可以选择把鼠标选择的模型制作为预制体,和根据传入一个地址,查找该目录下的模型进行处理这里可以,拓展为配表,为多个模型添加动画,添加什么动画,这个时候成功的给产品增加了工作,但是可以增加一些效率,需要处理的模型越多,越省时间
复制代码
AnimBool m_SelectionGameobjectWinWin;
    private string m_PrefabsRootPath = null;
    private string m_PrafabsParent = null;
    private string m_AnimatorControllerPath = null;
    private bool m_SetAnimatorController = false;
    AnimBool m_Win;
    private List<string> list = new List<string>();
    void OnEnable()
    {
        m_Win = new AnimBool(true);
        m_Win.valueChanged.AddListener(Repaint);

        m_SelectionGameobjectWinWin = new AnimBool(true);
        m_SelectionGameobjectWinWin.valueChanged.AddListener(Repaint);
    }


    void OnGUI()
    {
        m_SelectionGameobjectWinWin.target = EditorGUILayout.ToggleLeft("选择模型制作为预制体", m_SelectionGameobjectWinWin.target);

        if (EditorGUILayout.BeginFadeGroup(m_SelectionGameobjectWinWin.faded))
        {
            EditorGUI.indentLevel++;
            EditorGUILayout.PrefixLabel("预制体存放根路径");
            m_PrefabsRootPath = EditorGUILayout.TextField(m_PrefabsRootPath ?? "Assets/Prefabs/");
            EditorGUILayout.PrefixLabel("预制体存放文件夹名称");
            m_PrafabsParent = EditorGUILayout.TextField(m_PrafabsParent ?? "Other");
            m_SetAnimatorController = EditorGUILayout.Toggle("为该模型添加动画控制", m_SetAnimatorController);
            if (EditorGUILayout.BeginFadeGroup(m_SetAnimatorController == true ? 1.0f : 0))
            {
                EditorGUILayout.PrefixLabel("动画状态机存放文件夹名称");
                m_AnimatorControllerPath = EditorGUILayout.TextField(m_AnimatorControllerPath ?? "Assets/AnimatorControllers");
            }
            EditorGUILayout.EndFadeGroup();
            if (GUILayout.Button("把选择的模型制作为预制体", GUILayout.Width(200)))
            {
                if (Selection.gameObjects.Length > 0)
                {
                    Debug.LogError("根据CreationPrefabTool.GetAnimationClip()适配");
                    Close();
                }
                else
                {
                    Debug.LogError("请选择至少大于一个模型进行预制体制作!");
                    Close();
                }
            }
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndFadeGroup();

        m_Win.target = EditorGUILayout.ToggleLeft("批量模型制作为预制体", m_Win.target);

        if (EditorGUILayout.BeginFadeGroup(m_Win.faded))
        {
            EditorGUI.indentLevel++;
            EditorGUILayout.PrefixLabel("预制体存放根路径");
            m_PrefabsRootPath = EditorGUILayout.TextField(m_PrefabsRootPath ?? "Assets/Prefabs/");
            EditorGUILayout.PrefixLabel("模型存放根路径");
            for (int i = 0; i < list.Count; i++)
            {
                EditorGUILayout.BeginHorizontal("box");
                m_SetAnimatorController = EditorGUILayout.Toggle("为该模型添加动画控制", m_SetAnimatorController);
                if (EditorGUILayout.BeginFadeGroup(m_SetAnimatorController == true ? 1.0f : 0))
                {
                    EditorGUILayout.PrefixLabel("动画状态机存放文件夹名称");
                    m_AnimatorControllerPath = EditorGUILayout.TextField(m_AnimatorControllerPath ?? "Assets/AnimatorControllers");
                }
                EditorGUILayout.EndFadeGroup();
                list[i] = EditorGUILayout.TextField(list[i]);
                if (GUILayout.Button("Remove", GUILayout.Width(70)))
                {
                    list.RemoveAt(i);
                }
                EditorGUILayout.EndHorizontal();
            }
            if (GUILayout.Button("Add", GUILayout.Width(200)))
            {
                list.Add("");
            }
            if (GUILayout.Button("批量制作预制体", GUILayout.Width(200)))
            {
                CreationPrefabTool.MyCreationPrefab(list, m_PrefabsRootPath, m_SetAnimatorController, m_AnimatorControllerPath);
            }
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndFadeGroup();
    }
复制代码
这个窗口不是很完善,暂时没有需求就懒得完善了,啥是需要的在回来完善,暂时使用,没有出现bug
 
posted @   过往云烟吧  阅读(121)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示