Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by phort99 · Feb 23, 2014 at 09:52 AM · importassetdatabaseassetpostprocessor

How to update import settings for newly created asset during OnPostprocessAllAssets

I am writing a custom importer for my own filetype. The output of the importer is several Unity assets, such as a PNG and a prefab. The issue is that during OnPostprocessAllAssets I seem to be unable to refresh the asset database or import assets, so I can't set the import settings for the new asset.

Here is a standalone script that reproduces the issue. If you add a .foo file to your project, there will be an error setting the textureType since there is no asset found, and the import settings remain unchanged (the imported texture is compressed). If you use the "Test/CreateTestTexture()" menu item, the script works as expected (the imported texture is uncompressed). None of the available ImportAssetOptions seem to help either.

What appears to be happening is that Unity is specifically preventing recursion in OnPostProcessAllAssets by preventing assets from being imported while assets are being imported. I realize that this limitation is probably in place to prevent accidental editor crashes, but it's very restrictive on what I can do as far as importing assets.

Note that if you don't use a random filename for the output texture, the script works the second time the .foo asset is imported, since the texture already exists.

Is there some way to force the import or otherwise get Unity to recognize the new file at some stage of the import process? There's currently no OnPreprocessAllAssets so there's no way I could create the file ahead of time and hopefully have Unity recognize it in time to set the import settings when the texture is created.

 public class MyPostProcessor : AssetPostprocessor
 {
     [MenuItem("Test/CreateTestTexture()")]
     public static void CreateTestTexture()
     {
         Texture2D test = new Texture2D(128,128);
         Color32[] colorData = new Color32[128*128];
         for(int i = 0; i < colorData.Length; i++)
         {
             colorData[i] = new Color32((byte)(UnityEngine.Random.value*255),
                                        (byte)(UnityEngine.Random.value*255),
                                        (byte)(UnityEngine.Random.value*255),
                                        (byte)(UnityEngine.Random.value*255));
         }
         test.SetPixels32(colorData);
         test.Apply();
         test.name = UnityEngine.Random.value.ToString();
         string path = "Assets/" + test.name + ".png";
 
         byte[] pngTex = test.EncodeToPNG();
         File.WriteAllBytes(path, pngTex);

         Texture2D.DestroyImmediate(test);

         // Overwrite import settings
         AssetDatabase.ImportAsset(path);
         TextureImporter ti = (TextureImporter)TextureImporter.GetAtPath(path);
         ti.textureType = TextureImporterType.Advanced;
         ti.filterMode = FilterMode.Point;
         ti.textureFormat = TextureImporterFormat.AutomaticTruecolor;
     
         AssetDatabase.WriteImportSettingsIfDirty (path);
         AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
     }
 
     private static void OnPostprocessAllAssets(string[] importedAssets, 
             string[] deletedAssets, string[] movedAssets, string[] movedFromPath)
     {
         foreach(string asset in importedAssets)
         { 
             string extension = Path.GetExtension(asset);
             if (extension.ToLower() == ".foo")
             {
                 CreateTestTexture();
             }
         }
     }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by Deivore · Sep 09, 2018 at 04:28 PM

For the peeps coming across this on google, the reason this isn't working for @phort99 is twofold:

  1. As ModLunar mentions there's a call to AssetDatabase.Refresh(); that needs to be made and is missing in the code. It should be in the order they suggest: WriteAllBytes, AssetDatabase.Refresh(), then making a TextureImporter.

  2. Unfortunately, AssetDatabase.Refresh() works by an OnPostprocessAllAssets() call. @phort99 is calling this import function from within OnPostprocessAllAssets, and Unity won't let you call this function recursively. Therefore phort99's CreateTestTexture() needs to be called some other way, such as through a delegate hooked onto the EditorApplication.update CallBackFunction:

    private static EditorApplication.CallbackFunction _importDelegate;

      private static void OnPostprocessAllAssets(string[] importedAssets, 
                      string[] deletedAssets, string[] movedAssets, string[] movedFromPath)
              {
                  foreach(string asset in importedAssets)
                  { 
                      string extension = Path.GetExtension(asset);
                      if (extension.ToLower() == ".foo")
                      {
                          if (_importDelegate == null)
                          {
                             _importDelegate = new EditorApplication.CallbackFunction(CreateTestTexture);
                          }
                          EditorApplication.update = Delegate.Combine(EditorApplication.update, _importDelegate) as EditorApplication.CallbackFunction;
                      }
                  }
              }
    
    

Additionally their CreateTestTexture() function will need the following first line:

 EditorApplication.update = Delegate.Remove(EditorApplication.update, _importDelegate as EditorApplication.CallbackFunction) as EditorApplication.CallbackFunction;

If they eventually want to import a specific item rather than something totally randomly generated, they can save the filename to a static array in the OnPostProcessAllAssets call and reference the filenames and later delete them in the CreateTestTexture() call.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image patrik-org · Nov 27, 2020 at 09:44 PM 0
Share

Thanks a ton, saved me a lot of headache.

avatar image
0

Answer by Jordi-Bonastre · Mar 07, 2016 at 11:24 AM

If you add the OnPreprocessTexture function, you can manage your new .png and change the texture settings after creating it.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by ModLunar · Jun 16, 2017 at 12:19 PM

I'm not sure if this is what you were looking for, but I was coming across a similar problem. I was creating a new texture (.png) file, so I created the file first with something like this:

System.IO.File.WriteAllBytes("Assets/New Texture.png", originalTexture.EncodeToPNG());

What I found was then, to change the import settings of this newly created texture, I had to use this so Unity would recognize the newly created file:

AssetDatabase.Refresh();

Then, I could access the TextureImporter (the import settings, in this case, for a texture) by using

TextureImporter importer = (TextureImporter) AssetImporter.GetAtPath("Assets/New Texture.png");

Then, you're good to go with the importer to change whatever settings you'd like! This can all be in the same method -- you don't need any callbacks or waiting, so it's pretty convenient, but only works in the Editor. You also need to keep track of where the new file is located, and replace where I put my example path, "Assets/New Texture.png".

I hope this helps :)

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

22 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Running AssetDatabase.ImportPackage on multiple packages 3 Answers

Package Import with Postprocessor - How to tell when all assets are imported 1 Answer

Rename a clip using AssetPostProcessor 1 Answer

Is there a way to get a unique hash for an asset? 1 Answer

AssetDataBase.ImportAsset not triggering AssetProcessor.PreProcessModel 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges