【Unity】把美术导入的动画和模型自动生成为程序所需要的预制体
美术导入的资源格式千奇百怪,我们程序需要的预制体一般为标准格式,比如模型放一层,物理放一层,脚本放一层。所以我们需要手动设置一次结构,我做了个自动化工具就可以一键设置好结构了美术所给的动画文件
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; 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.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.Split('.'); strs = strs.Split('_'); var modelName = strs; 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/"; }}
页:
[1]