Unity 脚本去除导入FBX文件的顶点色,UV2,UV3

        确认导入的顶点色,UV2,UV3无效后,可以删除数据后结合fbxexport重新导出,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.Reflection;
using System.IO;
using Object = UnityEngine.Object;
using UnityEditor.VersionControl;

public class MeshOptimize : Editor
{
    [MenuItem("Assets/MeshOptimize(网格优化)/ClearMeshColor(清除模型顶点色)")]
    static void ClearMeshColor()
    {
        MeshOptimizeMethod(true, false);
    }

    [MenuItem("Assets/MeshOptimize(网格优化)/ClearMeshUV23(清除模型UV23)")]
    static void ClearMeshUV23()
    {
        MeshOptimizeMethod(false, true);
    }

    [MenuItem("Assets/MeshOptimize(网格优化)/ClearMeshColorUV23(清除模型顶点色和UV23)")]
    static void ClearMeshColorUV23()
    {
        MeshOptimizeMethod(true, true);
    }

    static void MeshOptimizeMethod(bool clearColor, bool clearUV23)
    {
        var objs = Selection.gameObjects;
        for (int i = 0; i < objs.Length; i++)
        {
            var obj = Selection.activeGameObject;

            foreach (var item in obj.GetComponentsInChildren<SkinnedMeshRenderer>(true))
            {
                //清除顶点色
                if (clearColor)
                {
                    item.sharedMesh.colors = null;
                }
                //清除uv2/uv3
                if (clearUV23)
                {
                    item.sharedMesh.uv2 = null;
                    item.sharedMesh.uv3 = null;
                }
            }


            foreach (var item in obj.GetComponentsInChildren<MeshFilter>(true))
            {
                //清除顶点色
                if (clearColor)
                {
                    item.sharedMesh.colors = null;
                }
                //清除uv2/uv3
                if (clearUV23)
                {
                    item.sharedMesh.uv2 = null;
                    item.sharedMesh.uv3 = null;
                }
            }

            ExportModel(obj);
            //如果导出新模型路径不在源模型路径,需要调用下面注释的代码刷新源模型的显示
            //AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(obj));//重新导入下,因为数据存在内存中,不重新导入,inspector视图会显示没有顶点色 和 uv23,编译后才会显示
        }
        AssetDatabase.Refresh();
    }

    static void ExportModel(Object obj, string sourcePath = "", string targetPath = "")
    {
        //空则通过asset获取路径
        if (string.IsNullOrEmpty(sourcePath))
        {
            sourcePath = AssetDatabase.GetAssetPath(obj);
        }
        //空表示直接覆盖原文件
        if (string.IsNullOrEmpty(targetPath))
        {
            targetPath = sourcePath;
        }

        //缓存meta文件,因为fbxexport会删掉初始的meta文件
        string tempFileName = Path.GetTempFileName();
        File.Copy($"{sourcePath}.meta", tempFileName, true);

        //反射获取导出类
        Type t = Assembly.Load("Unity.Formats.Fbx.Editor").GetType("UnityEditor.Formats.Fbx.Exporter.ModelExporter");
        //实例化导出对象
        var export = Activator.CreateInstance(t);
        //设置获取函数的条件
        BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance;
        //获取导出的函数
        MethodInfo methidInfo = t.GetMethod("ExportObject", flags);

        //导出设置修改,默认的不保留原model 的设置
        //反射获取设置类
        Type settingType = Assembly.Load("Unity.Formats.Fbx.Editor").GetType("UnityEditor.Formats.Fbx.Exporter.ExportModelSettingsSerialize");
        //实例化设置对象
        var setting = Activator.CreateInstance(settingType);
        // !!! !!!以下逻辑修改preserveImportSettings值,使导出时使用源文件的ImportSetting,但是没有效果,debug到info的值是对的,不清楚是不是跟派生类有关系,父类的此属性是直接返回的false,派生类重写了此属性的返回
        获取要修改的参数
        //FieldInfo info = settingType.GetField("preserveImportSettings", BindingFlags.NonPublic | BindingFlags.Default | BindingFlags.Instance);
        修改参数      
        //info.SetValue(setting, true);
        //获取要执行的函数,设置导出格式为 Binary ,提供 ASCII和Binary两张格式,前者文件体积过大
        MethodInfo SetExportFormatMethod = settingType.GetMethod("SetExportFormat", BindingFlags.Public | BindingFlags.Default | BindingFlags.Instance);
        SetExportFormatMethod.Invoke(setting, new object[] { 1 });//枚举无法调用,直接用int值代替

        //函数传参赋值
        object[] args = new object[]
        {
            targetPath,
            obj,
            setting
        };
        //执行函数
        methidInfo.Invoke(export, args);


        //路径不同,拷贝meta文件,即导入设置过去。路径相同则从上面缓存的文件中拷贝回来
        if (sourcePath != targetPath )
        {
            File.Copy($"{sourcePath}.meta", $"{targetPath}.meta", true);
        }
        else
        {
            File.Copy(tempFileName, $"{targetPath}.meta", true);
        }
        AssetDatabase.Refresh();
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值