Unity 之 自动设置导入资源属性选项(模型、图片、声音)

简介: 在项目开发中会经常性的更换、导入很多资源,而且对于资源的设置容易出现设置错误或者忘记设置的情况,下面的Code是用untyi自带的AssetPostprocessor功能把导入的资源根据一定的规则自动设置对应的格式选项,使用的时候也很方便,只需要把脚本...

在项目开发中会经常性的更换、导入很多资源,而且对于资源的设置容易出现设置错误或者忘记设置的情况,下面的Code是用untyi自带的AssetPostprocessor功能把导入的资源根据一定的规则自动设置对应的格式选项,使用的时候也很方便,只需要把脚本放在Editor文件夹下就可以

代码有相应的注释 可根据项目需求自定义即可,例如按照下面代码的例子是图片名称含有_UI字段的情况下(不分大小写),图片对应的TextureType自动设置成Sprite,音频之类的也是类似这种机制,模型方面会有精度压缩,在不影响模型效果的情况下降低对应的Asstbundle包体

简单示例如下

img_372c2034b393d75db1a88bc8e2b57efd.gif
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using System.Text.RegularExpressions;
using System;

public class EditorResourceSetting : AssetPostprocessor
{

    #region 模型处理
    //模型导入之前调用  
    public void OnPreprocessModel()
    {
        Debuger.Log("模型导入之前调用=" + this.assetPath);
        ModelImporter modelImporter = (ModelImporter)assetImporter;
        //模型优化
        //modelImporter.optimizeMesh = true;
        modelImporter.optimizeGameObjects = true;
        modelImporter.animationCompression = ModelImporterAnimationCompression.Optimal;
        modelImporter.animationRotationError = 1.0f;
        modelImporter.animationPositionError = 1.0f;
        modelImporter.animationScaleError = 1.0f;
    }
    //模型导入之后调用  
    public void OnPostprocessModel(GameObject go)
    {

        // for skeleton animations.
        Debuger.Log("模型导入之后调用  ");
        List<AnimationClip> animationClipList = new List<AnimationClip>(AnimationUtility.GetAnimationClips(go));
        if (animationClipList.Count == 0)
        {
            AnimationClip[] objectList = UnityEngine.Object.FindObjectsOfType(typeof(AnimationClip)) as AnimationClip[];
            animationClipList.AddRange(objectList);
        }

        foreach (AnimationClip theAnimation in animationClipList)
        {
            try
            {
                //  去除scale曲线
                //foreach (EditorCurveBinding theCurveBinding in AnimationUtility.GetCurveBindings(theAnimation))
                //{
                //    string name = theCurveBinding.propertyName.ToLower();
                //    if (name.Contains("scale"))
                //    {
                //        AnimationUtility.SetEditorCurve(theAnimation, theCurveBinding, null);
                //    }
                //}

                // 浮点数精度压缩到f3
                AnimationClipCurveData[] curves = null;
                curves = AnimationUtility.GetAllCurves(theAnimation);
                Keyframe key;
                Keyframe[] keyFrames;
                for (int ii = 0; ii < curves.Length; ++ii)
                {
                    AnimationClipCurveData curveDate = curves[ii];
                    if (curveDate.curve == null || curveDate.curve.keys == null)
                    {
                        //Debuger.LogWarning(string.Format("AnimationClipCurveData {0} don't have curve; Animation name {1} ", curveDate, animationPath));
                        continue;
                    }
                    keyFrames = curveDate.curve.keys;
                    for (int i = 0; i < keyFrames.Length; i++)
                    {
                        key = keyFrames[i];
                        key.value = float.Parse(key.value.ToString("f3"));
                        key.inTangent = float.Parse(key.inTangent.ToString("f3"));
                        key.outTangent = float.Parse(key.outTangent.ToString("f3"));
                        keyFrames[i] = key;
                    }
                    curveDate.curve.keys = keyFrames;
                    theAnimation.SetCurve(curveDate.path, curveDate.type, curveDate.propertyName, curveDate.curve);
                    Debuger.Log("设定数值");
                }
            }
            catch (System.Exception e)
            {
                Debuger.LogError(string.Format("CompressAnimationClip Failed !!! animationPath : {0} error: {1}", assetPath, e));
            }
        }
    }
    #endregion

    #region 纹理处理

    /// <summary>
    /// 检索Texture的类型是否为Sprite
    /// </summary>
    private string RetrivalTextureType = @"[_][Uu][Ii]";
    /// <summary>
    /// 检索Texture的MaxSize大小
    /// </summary>
    private string RetrivalTextureMaxSize = @"[&]\d{2,4}";
    /// <summary>
    /// 检索Texture是否为带Alpha通道
    /// </summary>
    private string RetrivalTextureIsAlpha = @"[Aa][Ll][Pp][Hh][Aa]";

    //纹理导入之前调用,针对入到的纹理进行设置
    public void OnPreprocessTexture()
    {
        string dirName = System.IO.Path.GetDirectoryName(assetPath);
        Debuger.Log(dirName);//从Asset开始的目录信息
        string folderStr = System.IO.Path.GetFileName(dirName);
        Debuger.Log(folderStr);//最近文件夹信息
        TextureImporter textureImporter = (TextureImporter)assetImporter;
        Debuger.Log(assetPath);//从Asset开始全路径
        string FileName = System.IO.Path.GetFileName(assetPath);
        Debuger.Log("导入文件名称:" + FileName);
        string[] FileNameArray = FileName.Split(new string[] { "_" }, System.StringSplitOptions.RemoveEmptyEntries);

        //含有UI指定字符,此图片是的类型为Sprite
        if (Regex.IsMatch(FileName, RetrivalTextureType))
        {
            Debuger.Log("含有指定字符");
            textureImporter.textureType = TextureImporterType.Sprite;
            textureImporter.mipmapEnabled = false;
        }
        else
        {
            textureImporter.textureType = TextureImporterType.Default;
            //textureImporter.mipmapEnabled = true;
        }

        //判断是否使用Alpha通道
        if (Regex.IsMatch(FileName, RetrivalTextureIsAlpha))
        {
            textureImporter.alphaIsTransparency = true;
        }
        else
        {
            textureImporter.alphaIsTransparency = false;
        }

        // 设置MaxSize尺寸
        Regex tempRegex = new Regex(RetrivalTextureMaxSize);
        if (tempRegex.IsMatch(FileName))
        {
            string MaxSizeStr = tempRegex.Match(FileName).Value.Replace("&", "");
            int TempMaxSize = Convert.ToInt32(MaxSizeStr);
            if (TempMaxSize < 50)
            {
                TempMaxSize = 32;
            }
            else if (TempMaxSize < 100)
            {
                TempMaxSize = 64;
            }
            else if (TempMaxSize < 150)
            {
                TempMaxSize = 128;
            }
            else if (TempMaxSize < 300)
            {
                TempMaxSize = 256;
            }
            else if (TempMaxSize < 600)
            {
                TempMaxSize = 512;
            }
            else
            {
                TempMaxSize = 1024;
            }
            textureImporter.maxTextureSize = TempMaxSize;
            Debuger.Log("设置的Texture尺寸为:" + TempMaxSize);
        }



        #region         -------------------------根据平台分别设置-------------------------------------
        // Debuger.Log("名称:" + textureImporter.GetDefaultPlatformTextureSettings().name);
        // TextureImporterPlatformSettings TempTexture = new TextureImporterPlatformSettings();
        // TempTexture.overridden = true;
        // TempTexture.name = "Android";
        // TempTexture.maxTextureSize = 512;
        // TempTexture.format = TextureImporterFormat.ETC_RGB4;
        // textureImporter.SetPlatformTextureSettings(TempTexture);
        // textureImporter.wrapMode = TextureWrapMode.Clamp;


        //textureImporter.maxTextureSize = 1024;
        //textureImporter.textureCompression = TextureImporterCompression.Compressed;
        //textureImporter.crunchedCompression = true;
        //textureImporter.compressionQuality = 60;
        #endregion
    }
    public void OnPostprocessTexture(Texture2D tex)
    {
        Debuger.Log("导入" + "tex" + "图片后处理");
    }

    void OnPostprocessSprites(Texture2D texture, Sprite[] sprites)
    {
        Debuger.Log("Sprites: " + sprites.Length);
        Debuger.Log("Texture2D: " + texture.name);
    }
    #endregion

    #region 音频处理
    public void OnPreprocessAudio()
    {
        Debuger.Log("音频导前预处理");

        AudioImporterSampleSettings AudioSetting = new AudioImporterSampleSettings();
        //加载方式选择
        AudioSetting.loadType = AudioClipLoadType.CompressedInMemory;
        //压缩方式选择
        AudioSetting.compressionFormat = AudioCompressionFormat.Vorbis;
        //设置播放质量
        AudioSetting.quality = 0.1f;
        //优化采样率
        AudioSetting.sampleRateSetting = AudioSampleRateSetting.OptimizeSampleRate;


        AudioImporter audio = assetImporter as AudioImporter;
        //开启单声道 
        audio.forceToMono = true;
        audio.preloadAudioData = true;
        audio.defaultSampleSettings = AudioSetting;

    }
    public void OnPostprocessAudio(AudioClip clip)
    {
        Debuger.Log("音频导后处理");
    }
    #endregion

    #region 其他处理
    //所有的资源的导入,删除,移动,都会调用此方法,注意,这个方法是static的  (这个是在对应资源的导入前后函数执行后触发)
    //public static void OnPostprocessAllAssets(string[] importedAsset, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    //{
    //    Debuger.Log("EditorResourceSetting", "有文件处理");

    //    foreach (string str in importedAsset)
    //    {
    //        Debuger.Log("导入文件 = " + str);

    //    }
    //    foreach (string str in deletedAssets)
    //    {
    //        Debuger.Log("删除文件 = " + str);
    //    }
    //    foreach (string str in movedAssets)
    //    {
    //        Debuger.Log("移动前文件 = " + str);
    //    }
    //    foreach (string str in movedFromAssetPaths)
    //    {
    //        Debuger.Log("移动后文件 = " + str);
    //    }
    //}
    /// <summary>
    /// 在对应的资源已经设置Assetbundle名称后更改其名称触发
    /// </summary>
    /// <param name="assetPath"></param>
    /// <param name="previousAssetBundleName"></param>
    /// <param name="newAssetBundleName"></param>
    public void OnPostprocessAssetbundleNameChanged(string assetPath, string previousAssetBundleName, string newAssetBundleName)
    {
        Debuger.Log("AssetBundle资源 " + assetPath + " 从名称: " + previousAssetBundleName + " 变更到: " + newAssetBundleName + ".");
    }

    /// <summary>
    /// 模型 max、maya数值相关
    /// </summary>
    /// <param name="go"></param>
    /// <param name="propNames"></param>
    /// <param name="values"></param>
    void OnPostprocessGameObjectWithUserProperties(GameObject go, string[] propNames, System.Object[] values)
    {
        //for (int i = 0; i < propNames.Length; i++)
        //{
        //    string propName = propNames[i];
        //    System.Object value = (System.Object)values[i];

        //    Debug.Log("Propname: " + propName + " value: " + values[i]);

        //    if (value.GetType().ToString() == "System.Int32")
        //    {
        //        int myInt = (int)value;
        //        // do something useful
        //    }

        //    // etc...
        //}
    }
    /// <summary>
    /// 模型 贴图相关
    /// </summary>
    /// <param name="material"></param>
    /// <param name="renderer"></param>
    public void OnAssignMaterialModel(Material material, Renderer renderer)
    {
        //Debug.Log("OnAssignMaterialModel");
    }

    //void OnPostprocessMaterial(Material material)
    //{
    //    material.color = Color.red;
    //    Debuger.Log("更改材质球");
    //}


    //将该函数添加到子类中,以便在导入模型(.fbx,.mb文件等)的动画之前获取通知。    这使您可以通过代码控制导入设置。
    void OnPreprocessAnimation()
    {
        //Debuger.Log("OnPreprocessAnimation");
        //var modelImporter = assetImporter as ModelImporter;
        //modelImporter.clipAnimations = modelImporter.defaultClipAnimations;
    }

    //private uint m_Version = 0;
    //public override uint GetVersion() { return m_Version; }
    #endregion

}

相关文章
|
4月前
|
图形学 C#
超实用!深度解析Unity引擎,手把手教你从零开始构建精美的2D平面冒险游戏,涵盖资源导入、角色控制与动画、碰撞检测等核心技巧,打造沉浸式游戏体验完全指南
【8月更文挑战第31天】本文是 Unity 2D 游戏开发的全面指南,手把手教你从零开始构建精美的平面冒险游戏。首先,通过 Unity Hub 创建 2D 项目并导入游戏资源。接着,编写 `PlayerController` 脚本来实现角色移动,并添加动画以增强视觉效果。最后,通过 Collider 2D 组件实现碰撞检测等游戏机制。每一步均展示 Unity 在 2D 游戏开发中的强大功能。
193 6
|
4月前
|
图形学 机器学习/深度学习 人工智能
颠覆传统游戏开发,解锁未来娱乐新纪元:深度解析如何运用Unity引擎结合机器学习技术,打造具备自我进化能力的智能游戏角色,彻底改变你的游戏体验——从基础设置到高级应用全面指南
【8月更文挑战第31天】本文探讨了如何在Unity中利用机器学习增强游戏智能。作为领先的游戏开发引擎,Unity通过ML-Agents Toolkit等工具支持AI代理的强化学习训练,使游戏角色能自主学习完成任务。文章提供了一个迷宫游戏示例及其C#脚本,展示了环境观察、动作响应及奖励机制的设计,并介绍了如何设置训练流程。此外,还提到了Unity与其他机器学习框架(如TensorFlow和PyTorch)的集成,以实现更复杂的游戏玩法。通过这些技术,游戏的智能化程度得以显著提升,为玩家带来更丰富的体验。
64 1
|
4月前
|
Java 网络安全 开发工具
UNITY与安卓⭐一、Android Studio初始设置
UNITY与安卓⭐一、Android Studio初始设置
|
4月前
|
API 开发工具 vr&ar
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
|
3月前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
154 0
|
3月前
|
图形学 开发者 搜索推荐
Unity Asset Store资源大解密:自制与现成素材的优劣对比分析,教你如何巧用海量资产加速游戏开发进度
【8月更文挑战第31天】游戏开发充满挑战,尤其对独立开发者或小团队而言。Unity Asset Store 提供了丰富的资源库,涵盖美术、模板、音频和脚本等,能显著加快开发进度。自制资源虽具个性化,但耗时长且需专业技能;而 Asset Store 的资源经官方审核,质量可靠,可大幅缩短开发周期,使开发者更专注于核心玩法。然而,使用第三方资源需注意版权问题,且可能需调整以适应特定需求。总体而言,合理利用 Asset Store 能显著提升开发效率和项目质量。
74 0
|
4月前
|
开发者 图形学 C#
深度解密:Unity游戏开发中的动画艺术——Mecanim状态机如何让游戏角色栩栩如生:从基础设置到高级状态切换的全面指南,助你打造流畅自然的游戏动画体验
【8月更文挑战第31天】Unity动画系统是游戏开发的关键部分,尤其适用于复杂角色动画。本文通过具体案例讲解Mecanim动画状态机的使用方法及原理。我们创建一个游戏角色并设计行走、奔跑和攻击动画,详细介绍动画状态机设置及脚本控制。首先导入动画资源并添加Animator组件,然后创建Animator Controller并设置状态间的转换条件。通过编写C#脚本(如PlayerMovement)控制动画状态切换,实现基于玩家输入的动画过渡。此方法不仅适用于游戏角色,还可用于任何需动态动画响应的对象,增强游戏的真实感与互动性。
105 0
|
4月前
|
开发者 图形学 iOS开发
掌握Unity的跨平台部署与发布秘籍,让你的游戏作品在多个平台上大放异彩——从基础设置到高级优化,深入解析一站式游戏开发解决方案的每一个细节,带你领略高效发布流程的魅力所在
【8月更文挑战第31天】跨平台游戏开发是当今游戏产业的热点,尤其在移动设备普及的背景下更为重要。作为领先的游戏开发引擎,Unity以其卓越的跨平台支持能力脱颖而出,能够将游戏轻松部署至iOS、Android、PC、Mac、Web及游戏主机等多个平台。本文通过杂文形式探讨Unity在各平台的部署与发布策略,并提供具体实例,涵盖项目设置、性能优化、打包流程及发布前准备等关键环节,助力开发者充分利用Unity的强大功能,实现多平台游戏开发。
106 0
|
4月前
|
图形学 C# 开发者
Unity粒子系统全解析:从基础设置到高级编程技巧,教你轻松玩转绚丽多彩的视觉特效,打造震撼游戏画面的终极指南
【8月更文挑战第31天】粒子系统是Unity引擎的强大功能,可创建动态视觉效果,如火焰、爆炸等。本文介绍如何在Unity中使用粒子系统,并提供示例代码。首先创建粒子系统,然后调整Emission、Shape、Color over Lifetime等模块参数,实现所需效果。此外,还可通过C#脚本实现更复杂的粒子效果,增强游戏视觉冲击力和沉浸感。
223 0
|
6月前
|
图形学 索引
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱4(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱4(附带项目源码)
109 2