Conditional Asset Importer

Table of Contents

1. Conditional Asset Importer

It is a pain customizing the import process of your assets per asset in the project through the inspector on by one.

It is possible to change the default settings Unity imports assets. You can do so by utilizing the AssetImporter class supplied by the Unity scripting API. Better yet you can use different import settings per asset type based on file name. In the source code section I’ve provided the class I’m using right now for my project. The source file must be under an Editor folder to work.

1.1 How to Use

  • Format your filenames as the below script dictates (you can customize the script for the filename format you desire)
  • Import your assets into the Unity project

You can setup your DCC tool to automatically add some prefix and/or postfix to your filename so you don’t have to rename your assets manually

1.2 Features

  • Changes and overrides desired settings based on desired filename sub-strings (e.g. texTransparentGrass.png imports it as transparent uncompressed texture if the code is customized as such) You can go crazy with the filename but beware not to go too crazy (texTransparentCompressedETC1NoMipMapGrassAniso2WrapRepeat.png)
  • Works on all asset types

1.3 Source Code

Provided source code is for a real project with specific needs and it’s customized as such. Look at all the values you can use in the Unity scripting reference for more options.

Check out the below url for all the platform name strings you can use https://docs.unity3d.com/ScriptReference/TextureImporterPlatformSettings-name.html

I’ve used #region where it makes sense for me. A school of thought states that it’s used for hiding ugly implementations or result in unreadable code thus it’s an evil practice. Feel free to remove them if you think so.

Renaming already imported assets doesn’t trigger a re-import if you’re using an editor extension that overrides the default renaming behavior (like SVN Tools for Unity). Thus you won’t see the effects of this script unless you re-import assets manually. Do so by right clicking on your asset and selecting the option “Reimport” from the context menu.

/* 
    An editor script that customizes the way assets are imported based on their file names
    Sarper Soher                                                 
    http://sarpersoher.com/unity3d/conditional-asset-importer/
*/

using UnityEditor;
using UnityEngine;

internal sealed class CustomAssetImporter : AssetPostprocessor {
#region Methods

#region Pre Processors

    private void OnPreprocessTexture() {
        // Extract the filename from the path
        var fileNameIndex = assetPath.LastIndexOf('/');
        var fileName      = assetPath.Substring(fileNameIndex + 1);

        // If the file name doesn't start with "tex" (e.g. texGrass.png) we won't change how it's imported, return
        // note: You can add as many such elements and change all the below settings based on these strings. Use StartsWith, EndsWith, Contains etc.
        if (!fileName.StartsWith("tex")) return;

        // Get a reference to the assetImporter which is contained in the class we've inherited from AssetPostProcessor
        var importer = assetImporter as TextureImporter;
        if (importer == null) return;

        // note: Some global settings I use for all the platforms, feel free to move these into settings below if they differ per-platform for you
        importer.textureType = TextureImporterType.Default;
        importer.anisoLevel  = 2;

        // Standalone
        // Construct the class that contains our importer settings, we'll re-use this class per platform by changing any fields we need changed
        // Let's start with standalone build target, "name" field determines the target platform
        var tips = new TextureImporterPlatformSettings() {
                                                             allowsAlphaSplitting = true,
                                                             compressionQuality   = 100,
                                                             crunchedCompression  = true,
                                                             format               = importer.DoesSourceTextureHaveAlpha() ? TextureImporterFormat.DXT5Crunched : TextureImporterFormat.DXT1Crunched,
                                                             maxTextureSize       = 4096,
                                                             name                 = "Standalone",
                                                             overridden           = true,
                                                             textureCompression   = TextureImporterCompression.CompressedHQ
                                                         };
        importer.SetPlatformTextureSettings(tips);

        // At this point we don't need to declare and define a settings class, just change the fields we want changed and re-use it!

        // WebGL
        tips.maxTextureSize = 1024;
        tips.name           = "WebGL";

        importer.SetPlatformTextureSettings(tips);

        // Windows Store Apps
        tips.name = "Windows Store Apps";

        importer.SetPlatformTextureSettings(tips);

        // iPhone
        tips.format         = importer.DoesSourceTextureHaveAlpha() ? TextureImporterFormat.PVRTC_RGBA2 : TextureImporterFormat.PVRTC_RGB2;
        tips.maxTextureSize = 1024;
        tips.name           = "iPhone";

        importer.SetPlatformTextureSettings(tips);

        // Android
        tips.compressionQuality  = 50;
        tips.crunchedCompression = false;
        tips.maxTextureSize      = 1024;
        tips.name                = "Android";

        tips.textureCompression = importer.DoesSourceTextureHaveAlpha() ?
                                      TextureImporterCompression.Uncompressed :
                                      TextureImporterCompression.Compressed;

        tips.format = importer.DoesSourceTextureHaveAlpha() ?
                          TextureImporterFormat.RGBA16 :
                          TextureImporterFormat.ETC_RGB4;

        importer.SetPlatformTextureSettings(tips);
    }

    private void OnPreprocessModel() {
        // Only get the filename, not the path
        var fileNameIndex = assetPath.LastIndexOf('/');
        var fileName      = assetPath.Substring(fileNameIndex + 1);

        if (!fileName.StartsWith("msh")) return;

        var importer = assetImporter as ModelImporter;
        if (importer == null) return;

        // If static
        if (assetPath.Contains("Stat")) {
            importer.animationType   = ModelImporterAnimationType.None;
            importer.importAnimation = false;

            // note: If you want to generate lightmap uv's for all the static meshes uncomment the lines below or create your own second uvs outside Unity
            // Unity does a bad job at generating lightmap uvs, causing all kinds of seams and hard edges
            // importer.generateSecondaryUV = true;
        }

        importer.globalScale     = 1;
        importer.importMaterials = false;

        // note There was a problem with mesh optimization, it would remove vertex colors, uncomment it if you don't utilize vertex colors
        //importer.optimizeMesh = true;
        importer.isReadable        = false;
        importer.importBlendShapes = false;
    }

    private void OnPreprocessAudio() {
        // Only get the filename, not the path
        var fileNameIndex = assetPath.LastIndexOf('/');
        var fileName      = assetPath.Substring(fileNameIndex + 1);

        if (!fileName.StartsWith("snd")) return;

        //var importer = assetImporter as AudioImporter;
    }

#endregion Pre Processors

#region Post Processors

    // Post processors get invoked after the asset is sucessfully imported, now we can edit the crated assets from our source files

    private void OnPostprocessTexture(Texture2D import) { }

    private void OnPostprocessModel(GameObject import) {
        // note: If all models with the name "Stat" are going to be static, uncomment the following lines
        //if(import.name.Contains("Stat"))
        //    import.isStatic = true;

        // Reset the rotation if the model came with one
        import.transform.position = Vector3.zero;
        import.transform.rotation = Quaternion.identity;
    }

    private void OnPostprocessAudio(AudioClip import) { }

#endregion Post Processors

#endregion Methods
}