找回密码
 立即注册
查看: 333|回复: 0

【Unity】把美术导入的动画和模型自动生成为程序所需要的预制体

[复制链接]
发表于 2022-5-16 15:37 | 显示全部楼层 |阅读模式
美术导入的资源格式千奇百怪,我们程序需要的预制体一般为标准格式,比如模型放一层,物理放一层,脚本放一层。所以我们需要手动设置一次结构,我做了个自动化工具就可以一键设置好结构了
美术所给的动画文件


image.png

自动生成工具


image.png

生成一个程序预制体和一个Animator文件


image.png

自动生成的controller文件


image.png

自动生成的预制体结构


image.png

下面是源码

using System.Collections;using System.Collections.Generic;using UnityEditor;using UnityEngine;namespace XFramework.AutoHandleAnimator{    public class AutoHandleAnimatorEditorWindow : EditorWindow    {        //动画文件        public static UnityEngine.Object aniObj;        //Prefab        public static UnityEngine.Object prefabObj;        [MenuItem("美术工具/生成程序预制体")]        public static void OpenWindow()        {            GetWindowWithRect<AutoHandleAnimatorEditorWindow>(new Rect(500, 500, 360, 360), false, "生成程序预制体", true);        }        private void OnGUI()        {            GUILayout.BeginVertical();            aniObj = EditorGUILayout.ObjectField("动画文件", aniObj, typeof(UnityEngine.GameObject), false);            prefabObj = EditorGUILayout.ObjectField("预制体文件", prefabObj, typeof(UnityEngine.GameObject), false);            if (GUILayout.Button("生成"))            {                if (aniObj != null && prefabObj != null)                {                    Generate();                    base.Close();                }            }            GUILayout.EndVertical();        }        private void Generate()        {            if (!aniObj.name.EndsWith("_Ani"))            {                Debug.LogError("动画文件不以 _Ani 结尾");                return;            }            if (!prefabObj.name.EndsWith("_Skin"))            {                Debug.LogError("预制体文件不以 _Skin 结尾");                return;            }            new AutoHandleAnimatorRequest().Generate(aniObj, prefabObj);        }    }}using System.Collections;using System.Collections.Generic;using UnityEditor;using UnityEditor.Animations;using UnityEngine;namespace XFramework.AutoHandleAnimator{    public class AutoHandleAnimatorRequest    {        public void Generate(Object aniObj, Object prefabObj)        {            var aniPath = AssetDatabase.GetAssetPath(aniObj);            Debug.Log("正在处理:" + aniPath);            Object[] objs = AssetDatabase.LoadAllAssetsAtPath(aniPath);            List<AnimationClip> clipsList = new List<AnimationClip>();            for (int i = 0; i < objs.Length; i++)            {                var obj = objs;                if (obj is AnimationClip)                {                    AnimationClip ac = obj as AnimationClip;                    if (ac.name.Contains("Take 001")) continue;//去除预览片段                    if (ac.name.Contains("__preview__")) continue;//去除预览片段                    clipsList.Add(ac);                }            }            var prefabName = GetModelName(aniPath);            var aniController = CreateAnimatorController(prefabName, clipsList);            CreatePrefab(prefabName, aniController, prefabObj);        }        private void CreatePrefab(string prefabName, AnimatorController controller, Object prefabObj)        {            GameObject prefabRoot = new GameObject(prefabName);            GameObject modelGo = GameObject.Instantiate(prefabObj as GameObject);            modelGo.name = prefabObj.name;            modelGo.transform.parent = prefabRoot.transform;            var animator = modelGo.AddComponent<Animator>();            animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;            animator.runtimeAnimatorController = controller;            var targetPath = AutoHandleAnimatorPathSetting.ModelExportPath + prefabName + ".prefab";            //保存角色预制体            PrefabUtility.SaveAsPrefabAssetAndConnect(prefabRoot, targetPath, InteractionMode.UserAction);            GameObject.DestroyImmediate(prefabRoot);            Debug.Log("create gameobject: " + targetPath);        }        private AnimatorController CreateAnimatorController(string prefabName, List<AnimationClip> clips)        {            var path = AutoHandleAnimatorPathSetting.ModelExportPath + prefabName + "_ani.controller";            AssetDatabase.DeleteAsset(path);            AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(path);            int rowCount = 8;//一列几个             int currentRow = 0;//当前列数            int currentRowCount = 0;//当前列clip个数            AnimatorStateMachine baseLayerMachine = animatorController.layers[0].stateMachine;            //空状态            baseLayerMachine.entryPosition = Vector3.zero;            baseLayerMachine.anyStatePosition = new Vector3(0f, 200f);            baseLayerMachine.AddState("null", new Vector3(0, 100f));            baseLayerMachine.exitPosition = new Vector3(0f, 300f);            //添加片段            for (int i = 0; i < clips.Count; i++)            {                if (i % rowCount == 0)                {                    currentRow += 1;                    currentRowCount = 0;                }                var x = currentRow * 300;                var y = currentRowCount * 100;                currentRowCount++;                AnimationClip clip = clips;                AnimatorState tempState = baseLayerMachine.AddState(clip.name, new Vector3(x, y, 0));                tempState.motion = clip;                EditorUtility.SetDirty(tempState);            }            EditorUtility.SetDirty(baseLayerMachine);            EditorUtility.SetDirty(animatorController);            Debug.Log("create controller: " + path);            return animatorController;        }        private string GetModelName(string path)        {            //女主角_Ani.FBX            var strs = path.Split('/');            strs = strs[strs.Length - 1].Split('.');            strs = strs[0].Split('_');            var modelName = strs[0];            return modelName;        }    }}路径设置

using System.Collections;using System.Collections.Generic;using UnityEngine;namespace XFramework.AutoHandleAnimator{    public static class AutoHandleAnimatorPathSetting    {        /// <summary>        /// 需要处理的模型根目录        /// </summary>        public const string ModelRootPath = "Assets/Arts/模型/角色/";        /// <summary>        /// 模型动画导出路径        /// </summary>        public const string ModelExportPath = "Assets/HotUpdateResources/Prefab/AutoCreateModel/";    }}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-22 11:19 , Processed in 0.093511 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表