Search Unity

Is there any way to take screenshot for each prefab?

Discussion in 'General Discussion' started by NoobCoderFake, Jul 25, 2018.

  1. NoobCoderFake

    NoobCoderFake

    Joined:
    Nov 24, 2015
    Posts:
    42
    Need to list many prefabs in an editor window, and the default way to show each prefab as a blue icon is meaningless, since we need to know how one prefab looks like in the camera.
    So what I want to do is:
    1. Instantiate one prefab in front of camera
    2. use ScreenCapture.CaptureScreenshot(fileName) to take a picture of it.
    3. destroy gameObject I've instantiate in step 1.
    4. goto step 1 to process next prefab.
    But the problem is, I need to do it in editor mode, and step 2 seems not a synchronize operation, thus gameObject will be destroyed before screenshot was done.
    Maybe I could create another thread to check target screenshot file was exist(means step 2 was finish) and then goto step 3. But that's not possible since Object.DestroyImmediate(go) and some other methods can only be called in main thread; and there is no Update() for editor to check that signal every frame.
    Is there any other way to get snapshot of those prefabs? Those prefabs are all UGUI prefab such as button/window/etc.
     
  2. NoobCoderFake

    NoobCoderFake

    Joined:
    Nov 24, 2015
    Posts:
    42
    OK, I've found a way to do it.
    First I need to create a canvas, set it's RenderMode to screen space - camera. and then bind a camera to it's RenderCamera field.
    Here is the code for screenshot:
    Code (CSharp):
    1. private static void DoSnapshot(GameObject go, Canvas canvas, Camera cam)
    2.     {
    3.         var ins = GameObject.Instantiate(go, canvas.transform, false);
    4.  
    5.         ins.SetActive(true);
    6.  
    7.         string fileName = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(go)) + ".png";
    8.         string astPath = "Assets/Prefabs/snapshots/" + fileName;
    9.         fileName = Application.dataPath + "/Prefabs/snapshots/" + fileName;
    10.         FileInfo info = new FileInfo(fileName);
    11.         if (info.Exists)
    12.             File.Delete(fileName);
    13.         else if (!info.Directory.Exists)
    14.             info.Directory.Create();
    15.      
    16.         var renderTarget = RenderTexture.GetTemporary(1920, 1080);
    17.         cam.aspect = 1920.0f/1080f;
    18.         cam.orthographic = true;
    19.         cam.targetTexture = renderTarget;
    20.         cam.Render();
    21.  
    22.         RenderTexture.active = renderTarget;
    23.         Texture2D tex = new Texture2D(renderTarget.width, renderTarget.height);
    24.         tex.ReadPixels(new Rect(0, 0, renderTarget.width, renderTarget.height), 0, 0);
    25.  
    26.         File.WriteAllBytes(fileName, tex.EncodeToPNG());
    27.  
    28.         cam.targetTexture = null;
    29.         Object.DestroyImmediate(ins);
    30.     }
     
  3. CityGen3D

    CityGen3D

    Joined:
    Nov 23, 2012
    Posts:
    681
  4. NoobCoderFake

    NoobCoderFake

    Joined:
    Nov 24, 2015
    Posts:
    42
    Thanks for your reply.
    AssetPreview.GetAssetPreview() is useful to get preview of meshes, and maybe some other type of assets, but not good for a uGUI prefab.
    I've finish it by take screenshot for each prefab, use code above, and it works fine.
     
    CityGen3D likes this.
  5. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    4,044
    I use a pretty similar process to generate item icons and character portraits.