Unity 如何批量修改FBX模型

由于模型数量有点多,并且都要修改参数,还有从里面提取动画。就搜搜查查,搞了个小工具,批量的修改 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

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

(0)

相关推荐

  • unity中点击某一个按钮播放某一个动作的操作

    1.创建动画控制器,双击打开动画控制器,创建 状态并添加动画片段,并且状态与状态之间进行连线,往返的都要有,在Animator的左上角–Parameters–点击加±-Trigger–命名(要求:第一个状态的名字+To+第二个状态的名字) 2.给状态与状态之间添加参数条件 选中状态与状态之间的线–检视视图上的Condition–点击+号–选择对应的参数条件 3.创建一个Button 切换到2D场景,在层级视图–Create–UI–Button按钮,调整到合适的位置,选中Canvas,把脚本挂上去

  • Unity 修改FBX模型动画的操作

    如何在Unity里修改FBX模型自带的动画 我们在把模型做成预制体的时候会出现,模型当前看到的位置和动画播放的位置不一致,而且模型动画文件又是只能读不能改 就这种情况 修改办法 选择模型的动画文件按Ctrl+D复制一份出来再修改就行了,然后在重新引用复制出来的新动画文件 补充:unity中对导入的FBX动画进行重新编辑 在unity中,当我们打开一个fbx自带的动画的时候,会发现动画的关键帧视灰色的,在动画的名字后面有(read-only)的字样,我们没有办法对fbx的动画进行重新编辑,在某些情

  • Unity 如何设定 Animator分割播放

    项目有个需求,一整段非常长的Animator 动画, 分割成一份份的播放,我们点击相应的按钮就播放某个时间点的动画,废话不多说 新建一个空物体加上toggle group, 下面是一堆的toggle并在Group里加上父亲 private Animator myAnimator; public List<Toggle> myTogglesList; private float playTime; public void Awake() { myAnimator = GameObject.Fin

  • Unity 实现给物体动态添加事件

    介绍一个方法给物体动态的添加事件(点击 拖拽等) using System.Events; using System.EventSystems; //_go is the gameobject which need add event //_go 是物体,因为EventTrigger是unity中的一个组件,我们要用添加组件的方式来给物体添加事件触发组件 //_type is the EventTriggerType(point , drag , clickdown...... //_type

  • Unity 点击UI与点击屏幕冲突的解决方案

    Unity 有点击屏幕进行移动操作,通过Input.GetMouseButtonDown(0).如果点击到了一些UI上面会触发点击屏幕事件. 引入UnityEngine.EventSystems,用函数判断一下即可 using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using UnityEngine.EventSystems; public class

  • Unity中EventTrigger的几种使用操作

    说起EventTrigger事件触发器,它的使用可以说是无处不在,EventTrigger继承了很多的事件接口,这些接口对我们开发是十分有用的. 弄懂EventTrigger在以后开发游戏过程中可以说是事半功倍. namespace UnityEngine.EventSystems { [AddComponentMenu ("Event/Event Trigger")] public class EventTrigger : MonoBehaviour, IEventSystemHan

  • Unity 按钮事件封装操作(EventTriggerListener)

    我就废话不多说了,大家还是直接看代码吧~ using UnityEngine; using UnityEngine.EventSystems; namespace Mx.UI { public class EventTriggerListener :UnityEngine.EventSystems.EventTrigger { public delegate void VoidDelegate(GameObject go); public VoidDelegate onClick; public

  • Unity中3DText显示模糊不清的解决方案

    在Unity中,当我们想要给3D物体一个文字说明时,使用Canvas下的Text虽然也能通过缩放实现,但是实现起来比较麻烦,改动的多,大小和位置也不容易控制. 此时就需要用到我们的3DText了,对于初次使用这个组件的"攻城狮"来说,会发现在Game场景中很模糊 具体修改操作如下: 此时,只需要选中当前3DText的物体,修改TextMesh组件下的Character Size和Font Size两个属性值.例如: 在这里,Character Size值越小,同时Font Size越大

  • unity 如何判断鼠标是否在哪个UI上(两种方法)

    第一种 可以得到UI,再根据名字判断是不是自己自己要点击的UI 其中参数canvas拖入此UI的canvas /// <summary> /// 获取鼠标停留处UI /// </summary> /// <param name="canvas"></param> /// <returns></returns> public GameObject GetOverUI(GameObject canvas) { Poin

  • Unity 如何批量修改FBX模型

    由于模型数量有点多,并且都要修改参数,还有从里面提取动画.就搜搜查查,搞了个小工具,批量的修改 FBX 模型的 参数,以及提取动画相关. using UnityEditor; using UnityEngine; using System.IO; using System.Collections; using System.Collections.Generic; public class ModifyMoidel : Editor { [MenuItem("BenBen/修改模型ModelSc

  • 使用python批量修改XML文件中图像的depth值

    最近刚刚接触深度学习,并尝试学习制作数据集,制作过程中发现了一个问题,现在跟大家分享一下.问题是这样的,在制作voc数据集时,我采集的是灰度图像,并已经用labelimg生成了每张图像对应的XML文件.训练时发现好多目标检测模型使用的训练集是彩色图像,因此特征提取网络的输入是m×m×3的维度的图像.所以我就想着把我采集的灰度图像的深度也改成3吧.批量修改了图像的深度后,发现XML中的depth也要由1改成3才行.如果重新对图像标注一遍生成XML文件的话太麻烦,所以就想用python批量处理一下.

  • expect实现批量修改linux密码脚本分享

    最近对linux批量执行的脚本很感兴趣,在网上到处找有关expect批量执行脚本,今天就给大家共享一个批量修改密码的脚本. 脚本内容: 复制代码 代码如下: #!/usr/bin/expect if { $argc<2 } {     send_user "usage: $argv0 <host file> <cmd file> \n"     exit }   # 机器列表数据格式:  IP  端口  旧密码  新密码 set hostfile    [

  • MySQL数据表字段内容的批量修改、清空、复制等更新命令

    最近遇到一点麻烦事,新安装的PHPwind6.0正式版社区在导入之前的会员帐号资料时,发现很多会员的mail地址貌似胡乱填写的,之前的PHPwind5.5版本没有开启mail地址验证功能,所以估计很多用户胡乱填写了email地址,所以我就想要求所有正式会员重新验证邮件地址来重新激活会员帐号,结果发现社区根本没有这项功能,挣扎了N久,数据库的会员资料数据表被反复安装=删除了好几遍,总算找到了一个批量修改的方法. 不过这样操作会连社区创建者的账号都改成未激活,所以要是不清楚还真的不敢动手. 在PHP

  • bat批处理批量修改文件扩展名的方法

    有的时候我们可能会遇到,在一个文件夹内有很多个文件,我们需要修改这些文件的扩展名,当然我们可以一个一个的修改,可是如果有很多文件,那就很麻烦了,所以今天就教大家批量修改文件扩展名的方法,希望大家能够灵活运用. 这里假设你要把扩展名为.gif的文件都改成.jpg格式,那么具体方法如下: 1.首先进入需要改扩展名的文件夹内新建一个记事本 2.在记事本中输入如下内容 复制代码 代码如下: ren *.gif *.jpg 3.将记事本的扩展名改名为.bat 4.双击运行bat文件即可批量将该文件夹下的所

  • 批处理实现批量修改文件名

    我们已经会使用循环命令对大量文件改名进行批量处理.但总结一下,该批处理并不是很健壮. 判断一个程序的好坏,往往不是站在程序员的角度,而从用户的角度出发. 比如:在用户使用它的时候,如果输入了不正确的路径格式怎么办?如果输入了含有非法符号的前缀怎么办?输入的扩展名也有问题怎么办?改完名后看不到是否执行成功的反馈信息,等等.带着这些想法,我们将原程序再次修改一下. :::::::批量修改文件名.bat::::::: @echo off title 批量修改文件名 setlocal EnableDel

  • 远程批量修改计算机IP设置的批处理

    网络IP设置远处更改脚本. 当网络整改需要大量IP修改的时候,可利用该脚本进行更改(重启计算机前不生效,可继续工作),然后等下班时间修改交换机配置,次日所有计算机启动后就可以用新IP工作了. 前提条件,知道域管理员密码或者所有计算机的本机管理员密码(后者比较麻烦),客户计算机为WIN2K或XP(防火墙开放135-139端口). 一条命令批量修改: for /l %i in (2,1,254) do net use //192.168.0.%i /user:admin@domain.com "pa

  • java批量修改文件名的实现方法

     java批量修改文件名的实现方法 初次学习java,被java的灵活性和简洁的思路所吸引 需求: 看到java视频在播放器列表中的文件名很长,每次都需要拉长列表才能看清全名,故写此代码批量修改该文件夹下所有文件名 实现代码: import java.io.*; class filesRename { public static void main(String[] args) throws IOException { String str1 = new String("这里是需要删除的文件名前

  • 解决Oracle批量修改问题

    问题:根据唯一字段编码修改其它字段,修改部分数据,数量在上万条数据,数据大,一开始就卡死了!笨办法,一条一条修改不知可年可月啊.其他方法个人原因实在是无能为力.如下: update ka02_new set aka065=1,aka166=1 where aka060='X-P02CA-A010-A001-2V'; update ka02_new set aka065=1,aka166=1 where aka060='X-P02CA-A010-A001-2W'; update ka02_new

随机推荐