- Home /
When and how to take a screenshot of a particle system from the editor?
I am writing an editor extension that, among other things, traverses the hierarchy of an object and takes thumbnail images of the components, depending on type. If it finds a texture, it writes the texture to a small PNG. If it finds a material, it applies the material to a model, instantiates it, takes a screenshot, and writes that screenshot to a small PNG. So far so good.
My problem is getting a snapshot of the particle system. I want to get to a time value of 0.1 seconds in the particle system and get a shot of what that looks like. Here's my code so far, with some irrelevant parts snipped.
DirectoryInfo ThumbBundlePack(Object asset) {
//...snip
//Explicit handling for types
switch (asset.GetType().ToString()) {
case "UnityEngine.Texture2D":
subdir = MakeSubdir();
//..snip
WriteThumbnail(asset as Texture2D, subdir);
MakePackage(asset, subdir);
break;
case "UnityEngine.Material":
subdir = MakeSubdir();
json.AddTags("material");
WriteThumbnail(asset as Material, subdir);
MakeBundle(asset, subdir);
MakePackage(asset, subdir);
break;
case "UnityEngine.Shader":
subdir = MakeSubdir();
json.AddTags("shader");
MakePackage(asset, subdir);
break;
default:
if (listed) {
subdir = MakeSubdir();
WriteThumbnail(asset, subdir);
MakeBundle(asset, subdir);
MakePackage(asset, subdir);
} else {
Debug.Log("Didn't handle: " + asset.ToString());
}
break;
}
return subdir;
}
void Snapshot(DirectoryInfo dir) {
//Has main camera save whatever is in the scene to the specified directory.
//Set up camera to take picture
RenderTexture shot = new RenderTexture(256,256,24);
Camera.main.targetTexture = shot;
Camera.main.Render();
RenderTexture.active = shot;
Texture2D tex = new Texture2D(256, 256, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(0,0,256,256), 0, 0);
//Write file
using (BinaryWriter bw = new BinaryWriter(File.Open(dir.ToString() + "/thumb.png", FileMode.Create))) {
bw.Write(tex.EncodeToPNG());
}
}
The version of WriteThumbnail() for textures - no problem:
void WriteThumbnail(Texture2D tex, DirectoryInfo dir) {
//Copy texture to readable so it can be manipulated
string tmptx = "Assets/3damsTempTex.png";
AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(tex), tmptx);
TextureImporter ti = (TextureImporter) TextureImporter.GetAtPath(tmptx);
ti.isReadable = true;
ti.compressionQuality = 30; //0-100
ti.textureFormat = TextureImporterFormat.ARGB32;
ti.mipmapEnabled = false;
AssetDatabase.ImportAsset(tmptx, ImportAssetOptions.ForceSynchronousImport);
Texture2D thumb = (Texture2D) AssetDatabase.LoadAssetAtPath(tmptx, typeof(Texture2D));
//Scale
TextureScale.Bilinear(thumb, 256, 256);
//Write file
using (BinaryWriter bw = new BinaryWriter(File.Open(dir.ToString() + "/thumb.png", FileMode.Create))) {
bw.Write(thumb.EncodeToPNG());
}
//Clean up temp asset
AssetDatabase.DeleteAsset(tmptx);
}
The version for materials - no problem:
void WriteThumbnail(Material mat, DirectoryInfo dir) {
//Apply material to default model, put in scene
GameObject model = (GameObject) Instantiate(AssetDatabase.LoadAssetAtPath("Assets/Editor/3dams/cube_bevelled.fbx", typeof(Object)));
model.renderer.material = mat;
Snapshot(dir);
DestroyImmediate(model);
}
Here's the trouble one - the version for generic objects, which checks to see if a particle system is attached:
void WriteThumbnail(Object prefab, DirectoryInfo dir) {
//Generic case, with special considerations for particle systems.
GameObject gobj = (GameObject) Instantiate(prefab);
if (gobj.GetComponent<ParticleSystem>()) {
Debug.Log("Found particle system in generic object");
ParticleSystem particles = gobj.GetComponent<ParticleSystem>();
particles.Play();
particles.time = 0.1f;
particles.Pause();
}
Snapshot(dir);
DestroyImmediate(gobj);
}
This works fine for textures and materials. But the screenshots for particle systems are showing up blank, just the background color of the scene. Any idea why, and what to do about it?
Hmm I haven't read the specifics of your code and stuff but I'm trying to do the same thing, and particle effects just don't seem to be rendering into my texture from Texture2D's ReadPixels(...) instanced method. But actually, when I save the texture as a PNG file in my project and switch Alpha Is Transparency off, I actually see my particle effects were rendered, but they're not writing anything to the screen's alpha values there. So they alpha values there stay considered 0, and I can't see them rendered unless there was some opaque geometry behind it -- where the particle effects will get drawn over it and be clearly seen.
I need to find a way to make the alpha values there greater than 0 so the particles show up. I'll see what I find.. I'll update this comment if I find out!
Your answer
Follow this Question
Related Questions
How do you force a particle system to play all the time in the editor, not just when it is selected? 5 Answers
How to play a particle system from the editor without selecting it 1 Answer
Start/Stop Playmode from editor script 10 Answers
Draw specific Object Inspector into Rect 1 Answer
Editor Window Views 0 Answers