Unity 4.2.0f pro batch mode Build script asset modifications not saved

Hello,

have a batch script (static function) that I use to build my targets using my continuous integration environment.
Before Unity v. 4.2.0 I had no problems in modifying assets before calling BuildPipeline.BuildPlayer( … ), but now I have some persistence issues.

I use my script to “cleanup” my dependency tree. Basically I go through some objects that retains texture references and I nullify all those object pointers to make Unity skip them when building my scene, I want them to not be embedded into my application.

basically I do:

CleanUpTextures()
BuildPipeline.BuildPlayer( scenes, targetDir, buildTarget, buildOptions );
DoOtherStuff()

Here’s the problem:

  • I nullify the references in CleanUpTextures and Debug.Log the output to assure this
  • I perform the build but I see that all the textures are included into the build (I see them under “Used Assets, sorted by uncompressed size:” into build log)
  • I print again the modifications issued in CleanUpTextures() and I see that are still valid (references are NULL)

the very same script was working in v 4.1.x

I’ve been trying with AssetDatabase.SaveAssets(), AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate), AssetDatabase.StartAssetEditing() / AssetDatabase.StopAssetEditing(), EditorUtility.SetDirty( myObjectWithTextureReference ) after modifications, but no luck

please help me, or just give me an hint

thank you

NOTE:
Please don’t ask if my textures are referenced somewhere else into my dependency tree, they are not, I can nullify my target references manually and the build will not include them.

Hello

I’ve made some discoveries about this misleading behaviour, and I’d like to share with my improvements

I’ve found out that the problem is originated by the execution of the code inside the -executeMethod environment

http://docs.unity3d.com/Documentation/Manual/CommandLineArguments.html

Basically in 4.2.0 it seems that you cannot rely on the EditorUtility.SetDirty(…), SaveAssets, Refresh and similar. It seems that you have somehow to force the editor to keep your changes. To save changes into my prefabs now I have to instantiate it, modify it, replace the original prefab with the new modified object and then destroy the instantiated one.

Example:

MyType tmpObj = PrefabUtility.InstantiatePrefab( objPrefab ) as MyType;
tmpObj.attribute = "modification";				
PrefabUtility.ReplacePrefab( tmpObj.gameObject, objPrefab );
DestroyImmediate( tmpObj );

But now here comes another problem with texture configurations. Inside my build pipeline I also convert and compress my textures using OnPreprocessTexture. It seems that Unity wont save my TextureImporter settings between different batch runs:

  • I launch Unity without /Library folder
  • Unity starts re-importing everything
  • OnPreprocessTexture is launched for every texture, it flows through my logic and Unity compress the texture in the way I want
  • Unity completes the build (batch process) and I can see the compressed textures into my build

Now I have a /Library folder

If I launch the batch build again with my Library folder in place I’d expect Unity to compare the TextureImporter settings of my previously compressed textures and re-compress them only if needed, but instead it re-compresses everything making every build veeery long. I’ve coded some guards and checks inside my OnPreprocessTexture functions to find out which settings are changes from the first and the second build, and I can see that the previously settings are not retained (textureFormat, SetPlatformTextureSettings-iOS, SetPlatformTextureSettings-Android).

I’ve been looking for a workaround to save the TextureImporter settings just like the one I’ve described above for the retention of Prefab modifications, but sadly there are no tools like prefabs for TextureImporter object so I cannot leverage on them as a workaround.

Some notes: I’ve been trying with SaveAssets / Refresh / SetDirty / Import … it’s just useless, TextureImporter changes are discarded at the end of the batch process.

I’m using 4.2.0 pro, please help me in fixing my continuous integration environment

Note: if you switch platforms, it will always require a reimport, no matter what.
To speed that up you must buy a Team License so you can add a cache server.
Then it will be able to load the various platforms assets straight from the cache server and will not require to reimport them every time.

Hi Dreamora

I’m not switching platform.

If I commit 2 sequential builds with no changes I have all my textures reimported two times.

Even reducing the process like this:

  1. OnPreprocessTexture executes a fixed logic, let’s say setting PVRTC RGBA 4bpp for every texture
  2. executeMethod calls a one line function: BuildPipeline.BuildPlayer( scenes, targetDir, EditorUserBuildSettings.activeBuildTarget, buildOptions )

I have Unity recompress all the textures on every build with no changes

I’m just trying to mimic the behaviour of the build process I’d have manually using Unity Editor menu buttons, but Unity thrashes my processed textures

In that case I missunderstood the intend behind the platform specific settings note.

Did you ensure to enable meta files? (I assume so cause otherwise your process would likely not even yield the right result)
Did you check if Unity is configured to compress textures on import? I’m unsure thats the default editor setting nowadays. Or do you force it in your preprocessor?
Are you doing anything with or to the library folder between the builds?

that being said I’ve not verified if it works fine in 4.2. 4.2.0 had a few deal breaker bugs so I skipped it and waited for the 4.2.1 that just happened

  • I use meta files + force text serialisation
  • I use compress texture on import (I confirm that’s the default behaviour)
  • Inside my OnPreprocessTexture function I just modify some of the texture’s TextureImporter object attributes (listed below)
importer.npotScale = TextureImporterNPOTScale.None;
importer.linearTexture = true;
importer.textureType = TextureImporterType.Advanced;
importer.mipmapEnabled = false;
importer.filterMode = FilterMode.Bilinear;
importer.textureFormat = format;
importer.maxTextureSize = 2048;
importer.compressionQuality = (int)TextureCompressionQuality.Best;
importer.SetPlatformTextureSettings( "iPhone", 2048, format, (int)TextureCompressionQuality.Best );
importer.SetPlatformTextureSettings( "Android", 2048, format, (int)TextureCompressionQuality.Best );

Obviously I can assure you that between the two sequential calls none of the above importer attributes are changed

Hey Arkanoid,

We are experiencing the same problem, in Unity 4.3.4. We happened to come across this post, curious if you ever pinged Unity about this as possibly being a bug introduced in 4.2? With what we are seeing (which seems to match exactly what you describe) it definitely feels like a bug.

-Stefan