Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only.

    Please, do not make any changes to your username or email addresses at id.unity.com during this transition time.

    It's still possible to reply to existing private message conversations during the migration, but any new replies you post will be missing after the main migration is complete. We'll do our best to migrate these messages in a follow-up step.

    On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live.


    Read our full announcement for more information and let us know if you have any questions.

Question How to add custom editor to AssetPostProcessor?

Discussion in 'Editor & General Support' started by mabulous, Aug 25, 2021.

  1. mabulous

    mabulous

    Joined:
    Jan 4, 2013
    Posts:
    198
    I have an AssetPostProcessor for .obj files

    I would like to add some options in the inspector of such assets that my AssetPostProcessor can use.

    How can this be achieved?

     
  2. fffMalzbier

    fffMalzbier

    Joined:
    Jun 14, 2011
    Posts:
    3,276
  3. mabulous

    mabulous

    Joined:
    Jan 4, 2013
    Posts:
    198
    If I understand correctly, scriptable importer can't be used for formats that unity supports already natively. I just want to give some per object settings to my PostProcessor - that must be possible somehow.
     
  4. mabulous

    mabulous

    Joined:
    Jan 4, 2013
    Posts:
    198
    Okay I found a way to do it. It's a bit hacky though since I need to use reflection to call an internal method of AssetImporterEditor in order to prevent some errors from happening. Also, it's using an editor instead of an AssetImporterEditor, but it does seem to work. If someone has a better solution, please let me know:

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Reflection;
    5. using UnityEditor;
    6. using UnityEditor.AssetImporters;
    7. using UnityEngine;
    8.  
    9. [CustomEditor(typeof(ModelImporter))]
    10. [CanEditMultipleObjects]
    11. public class CustomModelImporterEditor : Editor
    12. {
    13.   private AssetImporterEditor defaultEditor;
    14.  
    15.   private static readonly string TILE_COMPRESSION_ON = "tileCompressionOn";
    16.  
    17.   void OnEnable()
    18.   {
    19.     if(defaultEditor == null)
    20.     {
    21.       defaultEditor = (AssetImporterEditor)AssetImporterEditor.CreateEditor(targets,
    22.           Type.GetType("UnityEditor.ModelImporterEditor, UnityEditor"));
    23.       MethodInfo dynMethod = Type.GetType("UnityEditor.ModelImporterEditor, UnityEditor")
    24.                              .GetMethod("InternalSetAssetImporterTargetEditor",
    25.                                         BindingFlags.NonPublic | BindingFlags.Instance);
    26.       dynMethod.Invoke(defaultEditor, new object[] { this });
    27.     }
    28.   }
    29.  
    30.   void OnDisable()
    31.   {
    32.     defaultEditor.OnDisable();
    33.   }
    34.  
    35.   void OnDestroy()
    36.   {
    37.     defaultEditor.OnEnable();
    38.     DestroyImmediate(defaultEditor);
    39.   }
    40.  
    41.   public override void OnInspectorGUI()
    42.   {
    43.     defaultEditor.OnInspectorGUI();
    44.  
    45.     bool mixedValues = false;
    46.     bool tileCompressionOn =
    47.         Array.IndexOf(((ModelImporter)targets[0]).extraUserProperties, TILE_COMPRESSION_ON) > -1;
    48.     for (int i = 1; i < targets.Length; i++)
    49.     {
    50.       if(tileCompressionOn !=
    51.          (Array.IndexOf(((ModelImporter)targets[i]).extraUserProperties, TILE_COMPRESSION_ON) > -1))
    52.       {
    53.         mixedValues = true;
    54.         tileCompressionOn = true;
    55.         break;
    56.       }
    57.     }
    58.  
    59.     bool updateProperties = false;
    60.     if(mixedValues)
    61.     {
    62.       EditorGUI.showMixedValue = mixedValues;
    63.       updateProperties = EditorGUILayout.Toggle("Tile Compression", false);
    64.       EditorGUI.showMixedValue = false;
    65.     }
    66.     else
    67.     {
    68.       tileCompressionOn = EditorGUILayout.Toggle("Tile Compression", tileCompressionOn);
    69.       updateProperties = true;
    70.     }
    71.     if(updateProperties)
    72.     {
    73.       for (int i = 0; i < targets.Length; i++)
    74.       {
    75.         string[] extraUserProperties = ((ModelImporter)targets[i]).extraUserProperties;
    76.         if(tileCompressionOn && Array.IndexOf(extraUserProperties, TILE_COMPRESSION_ON) == -1)
    77.         {
    78.           // Add TILE_COMPRESSION_ON
    79.           List<string> props = new List<string>(extraUserProperties);
    80.           props.Add(TILE_COMPRESSION_ON);
    81.           ((ModelImporter)targets[i]).extraUserProperties = props.ToArray();
    82.         }
    83.         else if(!tileCompressionOn && Array.IndexOf(extraUserProperties, TILE_COMPRESSION_ON) > -1)
    84.         {
    85.           // Remove TILE_COMPRESSION_ON
    86.           List<string> props = new List<string>(extraUserProperties);
    87.           props.RemoveAll((string s) => { return s == TILE_COMPRESSION_ON; });
    88.           ((ModelImporter)targets[i]).extraUserProperties = props.ToArray();
    89.         }
    90.       }
    91.     }
    92.  
    93.     serializedObject.ApplyModifiedProperties();
    94.   }
    95. }
     
    julienkay, LazloBonin, Xtro and 2 others like this.
  5. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    833
    This seems to be the best solution so far (it doesn't have the issues from https://forum.unity.com/threads/how-to-override-model-importer-inspector.972678/ )

    However, I'm not sure why you enable the default editor in OnDestroy.

    I get a perfectly fine behaviour without that hack, and with a simpler approach of just destroying the default editor in OnDisable:
    Code (CSharp):
    1. private AssetImporterEditor defaultEditor;
    2.  
    3. public void OnEnable()
    4. {
    5.     defaultEditor = (AssetImporterEditor)CreateEditor(targets, Type.GetType("UnityEditor.ModelImporterEditor, UnityEditor"));
    6.     defaultEditor.AsDynamic().InternalSetAssetImporterTargetEditor(this); // AsDynamic() = ReflectionMagic library
    7. }
    8.  
    9. public void OnDisable()
    10. {
    11.     if (defaultEditor != null)
    12.     {
    13.         DestroyImmediate(defaultEditor);
    14.         defaultEditor = null;
    15.     }
    16. }
    17.