I’m working on an Editor script for SVGAssets that, given:
- a pow2 texture (512 x 256) asset, that is just for editor purposes, because it will be generated from an SVG text asset at runtime (i.e. just once initialization time) on the device:
- a set of sprite assets built from the texture:
- a scene where the sprites have been instantiated and positioned to form an orc character:
it should produce a build (BuildPipeline.BuildPlayer) such that it must not contain the whole 512 x 256 texture, but instead a dummy 1x1 texture, preserving all the sprite instances → sprites → texture linking.
Proceeding with the following operations, in this exact order:
- modify each sprite asset “resizing” its texture rectangle to a 1x1 pixel region, located in (0, 0)
// SpriteData is a custom class containing the Sprite plus addition related information (e.g. name, pivot, rect)
foreach (SpriteData spriteData in generatedSpritesAssets)
{
Sprite original = spriteData.sprite;
// we must reference the original texture, because we want to keep the file reference (rd->texture.IsValid())
Sprite tmpSprite = Sprite.Create(original.texture, new Rect(0, 0, 1, 1), new Vector2(0, 0), SVGAtlas.SPRITE_PIXELS_PER_UNIT);
// now we change the (sprite) asset content: actually we have just reduced its rectangle to a 1x1 pixel
EditorUtility.CopySerialized(tmpSprite, original);
}
- substitute texture asset content (i.e. pixels) with a 1x1 texture (backuping the original one)
// TextureBuildInfo is a custom class that maintains a (deep) copy of a given texture
public class TextureBuildInfo
{
public TextureBuildInfo(int width, int height, Color32[] srcPixels)
{
this.Width = width;
this.Height = height;
this.Pixels = new Color32[width * height];
System.Array.Copy(srcPixels, this.Pixels, srcPixels.Length);
}
public int Width;
public int Height;
public Color32[] Pixels;
}
// generate a 1x1 texture
Texture2D tmpTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false);
// list of textures clones
List<TextureBuildInfo> texturesClones = new List<TextureBuildInfo>();
// clone each generated texture
foreach (Texture2D original in generatedTexturesAssets)
{
TextureBuildInfo clone = new TextureBuildInfo(original.width, original.height, original.GetPixels32());
texturesClones.Add(clone);
// copy the 1x1 texture inside the original texture
EditorUtility.CopySerialized(tmpTexture, original);
}
- produce the build
// save modified assets (textures and sprites)
AssetDatabase.SaveAssets();
// build the player
BuildPipeline.BuildPlayer(null, "C:\\Temp\\unity_build", BuildTarget.StandaloneWindows, BuildOptions.None);
- restore the texture content
for (i = 0; i < generatedTexturesAssets.Count; i++)
{
Texture2D original = generatedTexturesAssets[i];
TextureBuildInfo clone = texturesClones[i];
Texture2D cloneTex = new Texture2D(clone.Width, clone.Height, TextureFormat.ARGB32, false);
cloneTex.SetPixels32(clone.Pixels);
// restore the original texture
EditorUtility.CopySerialized(cloneTex, original);
}
- restore sprites
foreach (SpriteData spriteData in generatedSpritesAssets)
{
Sprite original = spriteData.sprite;
Sprite tmpSprite = Sprite.Create(original.texture, spriteData.rect, spriteData.pivot, SVGAtlas.SPRITE_PIXELS_PER_UNIT);
// restore the original sprite
EditorUtility.CopySerialized(tmpSprite, original);
original.name = spriteData.name;
}
- update asset database
AssetDatabase.SaveAssets();
It seems that all is performed correctly:
- the buildPlayer is working as expected (it contains the 1x1 texture generating the right one at runtime)
- the texture asset is restored correctly (within the editor and in the Asset folder)
- the sprites assets are restored correctly (serialized sprite file assets looks identical: texture link is ok, vertices/uv are the same)
- the editor console does not display errors
but at the end of the script, the scene looks weird and wrong:
What could cause these glitches?
After closing and reopening the Unity editor, the scene and all the sprites looks good again.
Note that, after closing the Unity editor, assets files have not been changed.
I’ve tried both OpenGL and DirectX10 backends, Unity 4.5.5 on Windows 7.