Taking a screenshot and setting as a background image

I spent some time trying to take a screenshot of my randomly generated levels and set the image as a background in an effort to minimize the amount of textures the camera views. The thinking is currently I can have up to a 100x500 grid of textures making at worst 50,000 textures the camera has to render. If I can create my level map then take a picture of it and set that as the background then remove the textures it will help with rendering. This proved a bit harder than I thought due to how unity handles camera size and orientation. As you can see from the video I got it to work in theory and in practice but the image is not going to scale correctly once applied as a texture. I will need to set up some math so it scales properly.



For those who would like to see my code:
using UnityEngine;
using System.Collections;
using System.IO;
// This script is attched to the capture camera NOT the MainCamera.
public class CameraScreenCapture : MonoBehaviour
{
    public GameObject theBackground;
    Camera capCam;
    Camera mainCam;

    void Start()
    {
        mainCam = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<camera>();
        capCam = gameObject.GetComponent<camera>();
        capCam.enabled = false;
    }

    public IEnumerator TakeShot()
    {
        // If you have any canvas/UI items or GameObjects you do not want in the image turn them off here.
        mainCam.enabled = false;
        capCam.enabled = true;
        // wait for graphics to render
        //yield return new WaitForEndOfFrame();
        //Remember the size of the screenshot depends on the camera aspect ratio, orientation, and position!
        // To avoid odd scaling these should match. (Maths may be need for this)
        theBackground.transform.localScale = new Vector3(<size want you>;, <size want you>, <size want you>);
        capCam.orthographicSize = <size want you>;
        string str = Application.persistentDataPath;
        Application.CaptureScreenshot(str + "/thePic.png", 100);
        Debug.Log("Saved");
        // apply saved image as a texture
        try
        {
            theBackground.GetComponent<renderer>().material.mainTexture = LoadPNG(str + "/thePic.png");
            Debug.Log("Applied");
        }
        catch
        {
            Debug.LogError("Nope!");
        }
        // waiting for 200 milliseconds for image to capture and apply (Very hacky but works)
        yield return new WaitForSeconds(0.2f);
        mainCam.enabled = true;
        capCam.enabled = false;
        // enable any canvas/UI items or GameObjects you turned off at the start of the method.
    }

    void LateUpdate()
    {
        if (Input.GetKeyDown(KeyCode.L))
        {
            StartCoroutine(TakeShot());
        }
    }

    public static Texture2D LoadPNG(string filePath)
    {
        Texture2D tex = null;
        byte[] fileData;
        if (File.Exists(filePath))
        {
            fileData = File.ReadAllBytes(filePath);
            tex = new Texture2D(2, 2);
            tex.LoadImage(fileData); //..this will auto-resize the texture dimensions.
        }
        return tex;
    }
}

Comments

Popular posts from this blog

How to create slowly revealed text in a Unity 3d game

How different data structures can be used in game coding: List, Queue, and Stack

Adding randomness to your game through code using Unity 3d