Programmatically setting and saving the icon associated with an imported asset
<p>I have some auto-generated data being exported into my Unity project. To help me out I want to assign a custom icon to these assets to clearly identify them. This is of course simply possible via the editor itself, but ideally I'd like this to happen automatically on import. </p>

<p>To this effect I have written an AssetPostProcessor which should take care of this for me. In the example below (which applies to MonoScripts as an example but could apply to any kind of asset), all newly imported scripts will have the MyFancyIcon icon assigned to them. This update is both visible on the script assets themselves, as well as on the MonoBehaviours in the inspector. </p>

<pre><code>using UnityEngine;
using UnityEditor;
using System.Reflection;

public class IconAssignmentPostProcessor : AssetPostprocessor
{
    static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        Texture2D icon = AssetDatabase.LoadAssetAtPath&lt;Texture2D&gt;("Assets/Iconfolder/MyFancyIcon.png");
        foreach (string asset in importedAssets)
        {
            MonoScript script = AssetDatabase.LoadAssetAtPath&lt;MonoScript&gt;(asset);
            if(script != null)
            {
                PropertyInfo inspectorModeInfo = typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);
                SerializedObject serializedObject = new SerializedObject(script);
                inspectorModeInfo.SetValue(serializedObject, InspectorMode.Debug, null);
                SerializedProperty iconProperty = serializedObject.FindProperty("m_Icon");
                iconProperty.objectReferenceValue = icon;
                serializedObject.ApplyModifiedProperties();
                serializedObject.Update();

                EditorUtility.SetDirty(script);
            }
        }

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }    
}
</code></pre>

<p>And it works just fine, except for one problem. The updates aren't saved when closing the project and reopening it. To the best of my knowledge, either the <code>EditorUtility.SetDirty(script);</code> call should take care of this, or at the very least the <code>AssetDatabase.SaveAssets();</code> call. </p>

<p>However, looking at the difference between manually assigning an icon (which works) and doing it programmatically, there is an <code>icon</code> field in the meta files associated with the assets which does get set when manually assigning an icon, but not in my scripted case. (In the scripted case the meta files aren't even updated) </p>

<p>So what gives? Do I have to do anything in particular when it's (apparently) only meta data I'm changing? Is there anything simple I'm overlooking? </p>