Manage Default Asset Import Settings in Unity

Example source code and project, Defaults Importer

If you’ve worked on Unity in a more production like environment, or perhaps had to tackle optimizing a project to run better on mobile devices, you will have no doubt experienced the problem of having to manage the import settings on all of your assets. Unfortunately this process is subject to errors, as often the defaults provided don’t always match your needs and when working with other team members tends to be overlooked.

Fortunately it is only a small amount of effort to write a set of asset importers to handle most of this work for you using the AssetPostProcessor class (it preprocesses too).

Creating a project for your importer

Before getting to the preprocessing functions themselves it is worth mentioning some important points about how importing works, and how we will setup our importer project.

In the Unity Scripting Reference entry for the AssetPostProcessor it mentions that you should create your importers in a separate DLL which is then placed somewhere within the Editor folder. This is very important as Unity checks assets first to see if they have been changed so that it can skip the import if it is already done. Along with the contents of an asset, the importers and their versions will also be checked and an asset reimported if a change is found. If, for example, you place an importer script directly into your project Unity will import the assets with that script. If afterwards you should write or change another script in the Editor folder and it fails to compile, the postprocessor will also not be compiled. To Unity this will appear as a change requiring all assets to be reimported–an often very time consuming process. Using a DLL guarantees the availability of the importer avoiding this problem.

Creating the DLL will mean creating an external project. I personally use Xamarin with a mono backend to ensure no issues (though technically any .NET 3.5 lib should be supported). In Xamarin studio create a new C# library project targeting the Mono / .NET 3.5 framework and import the UnityEngine and UnityEditor assemblies into the project references. Refer to the images below.

Target Framework Settings ImageReference Unity Assemblies Image

 

Unity can be a bit picky about the target framework, I found problems importing when using the MS build engine in Xamarin Studio so be sure to check these settings if you get any errors loading the assembly.

Assigning defaults during preprocessing

There are three types of assets than can be preprocessed using this approach: Models, Textures and Audio.

Textures

 public void OnPreprocessTexture()
 {
     if (!isAssetProcessed)
     {
         var textureImporter = assetImporter as TextureImporter;
         textureImporter.compressionQuality = 100;
         textureImporter.filterMode = FilterMode.Bilinear;
         textureImporter.maxTextureSize = 2048;
         textureImporter.textureFormat = TextureImporterFormat.AutomaticCompressed;
     }
 }

Audio

 public void OnPreprocessAudio()
 {
     if (isAssetProcessed)
     {
         var audioImporter = assetImporter as AudioImporter;
         audioImporter.forceToMono = false;
         audioImporter.compressionBitrate = 128000;
         audioImporter.format = AudioImporterFormat.Compressed;
         audioImporter.hardware = false;
         audioImporter.loadType = AudioImporterLoadType.DecompressOnLoad;
 
         if (assetPath.Contains("Streaming"))
             audioImporter.loadType = AudioImporterLoadType.StreamFromDisc;
     }
 } 

When importing audio you may want to separate out the settings for sounds effects and streaming audio (music). Here we do this simply by checking the asset path for the word Streaming. You can use this same approach on any asset for finer control of how defaults should be applied.

Models

 public void OnPreprocessModel()
 {
     if (!isAssetProcessed)
     {
         var modelImporter = assetImporter as ModelImporter;
         modelImporter.addCollider = false;
         modelImporter.animationCompression = ModelImporterAnimationCompression.KeyframeReduction;
         modelImporter.generateAnimations = ModelImporterGenerateAnimations.None;
         modelImporter.importAnimation = false;
         modelImporter.importMaterials = false;
         modelImporter.tangentImportMode = ModelImporterTangentSpaceMode.None;
         modelImporter.globalScale = 1f;
         modelImporter.isReadable = false;
         modelImporter.meshCompression = ModelImporterMeshCompression.Low;
         modelImporter.optimizeMesh = true;
     }
 }

Overriding the default settings

When using preprocessors you may notice that every time an asset is changed (or reimported) that the settings will go back to their defaults. This might be very handy if you do not want the settings to be changed, however sometimes it is necessary to make customizations beyond the defaults. To do this we simply need to track, using assetImporter.userData field, when an initial import is done so that further changes to these settings are not overwritten.

 static readonly string DEFAULTS_KEY = "DEFAULTS_DONE";
 static readonly uint DEFAULTS_VERSION = 2;
 
 public bool isAssetProcessed
 {
     get
     {
         string key = string.Format("{0}_{1}", DEFAULTS_KEY, DEFAULTS_VERSION);
         return assetImporter.userData.Contains(key);
     }
     set
     {
         string key = string.Format("{0}_{1}", DEFAULTS_KEY, DEFAULTS_VERSION);
         assetImporter.userData = value ? key : string.Empty;
     }
 }

You will need to make certain that no other importers in your project write to the userData field or use a more elaborate way of sharing the same field such as through a JSON structure. Then at the end of each preprocess function simply add the following line:

 isAssetProcessed = true;

That’s it! With this simple system you can enforce some sane import settings to help take the need for management out of the process.

License

Creative Commons License
Asset Defaults Importer by Clifford Roche is licensed under a Creative Commons Attribution 4.0 International License.

Leave a Reply

Your email address will not be published. Required fields are marked *