Comunidad orientada al desarrollo de videojuegos

Unity3D ScreenShots

Vamos a ver una utilidad sencilla y rápida de implementar en nuestros juegos, son las capturas de pantalla. Hoy en día la mayoría de dispositivos móviles pueden sacar una captura de pantalla con una combinación de botones, pero nosotros podemos hacerlo por programación en Unity3D y puede resultar útil para capturar ese momento crucial de nuestro juego, como puede ser un gol en un juego de futbol, un golpe vencedor en un juego de lucha o la foto finish en al entrada a meta en un juego de carreras.

Lo primero es preparar la escena para obtener nuestras capturas de pantalla, yo he colocado un cubo en el centro de la pantalla y una Directional light para q se vea bien el cubo.

 

image

 

Ya tenemos algo para sacar las capturas, pero siempre va a ser la misma, así que he creado un script que hace que se rote el modelo.

void Start()
{
rigidbody.AddTorque(1, 2.5f, 5);
}

Para poder usar este script, es necesario que nuestro modelo tenga un componente Rigidbody que hay que ponérselo a mano.

Ok, si le habéis asignado el Script al cubo, ahora este rotará en la escena, permitiéndonos sacar varias screenshots diferentes.

 

Ahora creamos un nuevo script para obtener las capturas de pantalla.

public class ScreenShotter : MonoBehaviour
{
void OnGUI()
{
if (GUI.Button(new Rect(0, 0, 100, 50), "ScreenShot"))
{
Application.CaptureScreenshot("ScreenShot.png");
}
}
}

Con una sencilla línea ( Application.CaptureScreenshot(“ScreenShot.png”); ) obtenemos una captura de pantalla y la grabamos en disco. Cuando pulsemos el botón, guardaremos la captura de pantalla en el directorio raíz, si ya existe, se sobrescribe. Podemos jugar un poco mas con este método, tiene un parámetro mas, “superSize” que lo que hace es escalar la imagen a la cantidad indicada. También podemos indicarle una ruta a la imagen donde queremos que se guarde y configurar el nombre de la imagen para q no se repita.

Application.CaptureScreenshot((Application.persistentDataPath + String.Format("/ScreenShot{0}.png", System.DateTime.Now.ToString("_d-MMM-yyyy-HH-mm-ss-f"))), 3);

Bien, esta línea, lo que hace es obtener un directorio estándar de la plataforma y guardaremos la imagen en formato PNG añadiéndole la fecha y hora al nombre para que no se repita nunca. Debéis notar que he añadido la barra “/” antes del nombre de la imagen. Además, la imagen la saca 3 veces mas grande.

Si no sabéis donde habéis guardado la imagen, podéis poner esta línea “print(Application.persistentDataPath)” para ver el directorio donde esta la imagen.

 

Con esta función que nos proporciona Unity3D es muy sencillo sacar una screenshot, vamos a complicarlo un poco. En lugar de usar este método, lo que vamos a hacer es obtener los los pixeles de la pantalla y vamos a guardarlos a mano.

Para poder hacer esto, necesitamos esperar a que el tiempo para la captura de pantalla este listo, si intentamos obtener una captura de pantalla cuando se esta escribiendo el buffer de pantalla, obtendremos un error. Usaremos una Coroutine y aplicaremos el comando WaitForEndOfFrame

void OnGUI()
{
if (GUI.Button(new Rect(0, 60, 100, 50), "SS Manual"))
{
StartCoroutine(ScreenShotManual());
}
}

private IEnumerator ScreenShotManual()
{
yield return new WaitForEndOfFrame();
Rect rect = new Rect(0, 0, Screen.width, Screen.height);
Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
texture.ReadPixels(rect, 0, 0);
texture.Apply();
byte[] bytes = texture.EncodeToPNG();
Destroy(texture);
File.WriteAllBytes((Application.persistentDataPath + String.Format("/ScreenShot{0}.png", System.DateTime.Now.ToString("_d-MMM-yyyy-HH-mm-ss-f"))), bytes);
}

 

Ok, son muchas líneas nuevas. Lo primero es destacar lo que os he comentado antes del código, meterlo todo dentro de una Coroutine y esperar a que el frame este listo para tomar una captura de pantalla. Después, nos creamos un rectángulo en la posición y tamaño que queremos capturar, en nuestro caso es la pantalla entera. Después creamos una textura de ese tamaño y leemos los pixeles con ReadPixels que se almacenan dentro de la textura, y por último, pasamos la textura a formato PNG y la escribimos en el mismo directorio y con la misma nomenclatura de nombres que estábamos haciendo en el caso anterior.

Es mas complejo y estaréis pensando que para que sirve este método si ya tenemos el anterior, pues bien, este método es interesante, porque podemos modificar la imagen obtenida por código, aplicándole filtros o marcas de agua, o bien podemos obtener una captura de pantalla de una determinada zona, en lugar de la pantalla entera.

Aquí tenéis el proyecto: https://db.tt/UzmTBc8S

Espero que os sirva para vuestros juegos, un saludo.

, ,

4 thoughts on “Unity3D ScreenShots

  • Bueno, lei el post, y la verdad me senti un poco perdido, aunque eso es pk se poco de programación, pk igualmente logre hacer que me salga el boton de captura, peeeero, no me funciona, intente poner el script que nos brindas vos para trabajar, pero me pasa lo mismo, me sale el boton, pero no me funciona, me gustaria saber que puede ser el problema.

    Lo estoy aplicando en un App de realidad aumentada que estoy haciendo para android e IOS, y el script lo aplico sobre la camara AR

    • Administrator says:

      Hola,

      ¿Podrías explicar un poco mas en que te falla? ¿da algún error o no te guarda la imagen?

      Que plugin de RA estas usando, ¿Vuforia? ¿Que versión es?

      • Pedro says:

        Hola, me pasa el mismo error, estoy usando ese método y no pasa nada. Estoy usando Vuforia, sobre un iPad 2.

        Saludos

  • Erick says:

    Hola, yo tambien baje el proyecto y no funciona, aunque no saca ningun error no se en donde guarda las imagenes.

    Yo estoy usando unity 5.0 nose si eso tenga que ver

    Erick

Leave a Reply