Unity 如何批量修改FBX模型

时间:2021-05-20

由于模型数量有点多,并且都要修改参数,还有从里面提取动画。就搜搜查查,搞了个小工具,批量的修改 FBX 模型的 参数,以及提取动画相关。

using UnityEditor;using UnityEngine;using System.IO;using System.Collections;using System.Collections.Generic;public class ModifyMoidel : Editor{ [MenuItem("BenBen/修改模型ModelScal")] public static void ModifyMoidelScale() { List<string> paths = new List<string>(); foreach (Object o in Selection.GetFiltered(typeof(Object), SelectionMode.Assets)) { Debug.Log(o.name); //非对象不继续 if (!(o is GameObject)) continue; //将o作为模型存储在mod中 //Debug.LogWarning(o.name); GameObject mod = o as GameObject; //将mod模型路径存储在path中 string path = AssetDatabase.GetAssetPath(mod); ModelImporter modelimporter = ModelImporter.GetAtPath(path) as ModelImporter; if (!modelimporter) { UnityEngine.Debug.LogError(string.Format("path-->{0}<---不是ModelImporter", path)); continue; } //修改Model 下的Scale Factor modelimporter.globalScale = 10; paths.Add(path); AssetDatabase.ImportAsset(path); } AssetDatabase.Refresh(); CreatNewAnimations(paths); } private static void CreatNewAnimations(List<string> paths) { UnityEditor.Animations.AnimatorController animatorController = null; UnityEditor.Animations.AnimatorControllerLayer layer = null; UnityEditor.Animations.AnimatorStateMachine asm = null; Debug.Log(paths.Count); for (int i = 0; i < paths.Count; i++) { paths[i].Replace("\\", "/"); AnimationClip newClip = new AnimationClip(); AnimationClip clip = AssetDatabase.LoadAssetAtPath(paths[i], typeof(AnimationClip)) as AnimationClip; if (!clip) { UnityEngine.Debug.LogError(string.Format("path-->{0}<--不包含AnimationClip", paths[i])); continue; } string fbxName = Path.GetFileNameWithoutExtension(paths[i]); fbxName = fbxName.Substring(fbxName.LastIndexOf("_") + 1); //新的AnimationClip名字 var newClipName = GetAniName(int.Parse(fbxName)) + ".anim"; string directoryPath = paths[i].Replace(Path.GetFileName(paths[i]), "AnimationClip/"); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } EditorCurveBinding[] binding = AnimationUtility.GetCurveBindings(clip); for (int j = 0; j < binding.Length; j++) { AnimationCurve animationCurve = AnimationUtility.GetEditorCurve(clip, binding[j]); AnimationUtility.SetEditorCurve(newClip, binding[j], animationCurve); } //非Legacy动画使用GetCurveBindings、GetEditorCurve和SetEditorCurve方法 //Legacy要使用GetObjectReferenceCurveBindings、GetObjectReferenceCurve和SetObjectReferenceCurve方法 //设置AnimationClipSettings AnimationUtility.SetAnimationClipSettings(newClip, AnimationUtility.GetAnimationClipSettings(clip)); string newClipPath = directoryPath + newClipName; AssetDatabase.CreateAsset(newClip, newClipPath); //生成animator if (!animatorController) { animatorController = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(directoryPath + "Animator.controller"); layer = animatorController.layers[0]; asm = layer.stateMachine; } //添加到Animator中 UnityEditor.Animations.AnimatorState state = asm.AddState(newClip.name); state.motion = newClip; //如果是Idle 动画,设置loop if (newClip.name == "Idle") { AnimationClipSettings animationClipSettings = AnimationUtility.GetAnimationClipSettings(newClip); animationClipSettings.loopTime = true; AnimationUtility.SetAnimationClipSettings(newClip, animationClipSettings); layer.stateMachine.defaultState = state; } AssetDatabase.ImportAsset(paths[i]); } AssetDatabase.Refresh(); } private static string GetAniName(int count) { switch (count) { case 1: return "Idle"; case 2: return "2-1"; case 3: return "2-2"; case 4: return "2-3"; case 5: return "2-4"; default: return ""; } }}

如果有更简单的实现方法欢迎各位大佬留言。

补充:Unity 动态修改prefab 同步fbx

有时候我们想prefab和fbx无缝切换怎么办,也就是在unity里调完效果后不满意,返回dcc如阿健修改模型,但是prefab上又挂载了东西,不想重拖怎么办?这时候prefab variant就又用途了

建立变体,把变体拖到场景里。

或者先拖fbx到场景,再选择变体放置。

然后修改好模型后,直接再在文件浏览器里替换同名prefab

貌似需要到prefab模式里再revert一下

这样就可以实现“动态”修改perfab了。没改变的话可以右键相关属性revert

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章