ACTUALIZACIÓN IMPORTANTE
He creado una solución más completa y simple de utilizar, se trata de un paquete de Unity para descargar e importar, con un prefabricado que al arrastrarlo al Canvas automáticamente produce el efecto de fundido que le configuremos en los parámetros del inspector.
Puedes descargar el paquete con esta solución en el siguiente link:
Descargar Asset: Efecto de fundido para Unity
En el vídeo de abajo explico cómo usar esta solución, pero no cómo funciona, si te interesa saber sobre el funcionamiento a nivel de programación continúa leyendo este artículo.
CONTINÚA EL ARTÍCULO ANTIGUO
Introducción
En este artículo vamos a ver una manera simple de oscurecer la pantalla en Unity utilizando una componente imagen. Esto nos puede ser muy útil por ejemplo para usar como transición en un cambio de escena.
En el siguiente video se ve el resultado que obtendremos al finalizar.
Video explicativo y descargas
En el video se explica cómo funciona la solución, pero no se hace paso a paso.
🟢 VÍDEO: Cómo usar EFECTO FADE IN/FADE OUT
Descargar scripts GameController y UIManager.
Resolución paso a paso
Elementos de la jerarquía
Vamos a crear todos los elementos necesarios para resolver el problema. En primer lugar un empty GameObject que llamaremos «GameController» y un GameObject tipo Canvas que es el que contendrá todos los elementos de la interfaz gráfica.
En la figura 3 vemos estos elementos creados y colocados al principio de la jerarquía.
Imagen para oscurecer la pantalla
Lo siguiente que hacemos es crear una Imagen como hijo del GameObject UI. Esta imagen usaremos para bloquear la visión de la cámara.
En el inspector en la componente imagen hacemos que el color sea negro.
Configurar Canvas Scaler
Vamos al GameObject UI y en el inspector, en la componente CanvasScaler seleccionamos el modo «Scale with screen size» en el campo «UI Scale Mode» (figura 6). Con esto logramos que los elementos de la interfaz gráfica modifiquen su tamaño en función del tamaño de la pantalla.
Para la resolución de referencia vamos a usar 1920 x 1080 pixels, que se conoce como resolución FullHD.
La configuración del CanvasScaler conviene hacerla al principio, antes de colocar los elementos de la interfaz gráfica. Sino luego tendremos que volver a modificar todos los elementos para que se ajusten a la nueva configuración.
Volvemos al GameObject imagen y ajustamos su tamaño a 1920 x 1080 para que cubra toda la pantalla. Si todo funciona bien la pantalla se debería ver como en la figura 9.
En el color negro de la imagen vamos a hacer que la componente Alfa sea 0, de esta forma será transparente.
Ahora vamos a crear un par de botones para ejecutar las funciones que posteriormente definiremos en los Scripts.
Botones
Al primero vamos a llamarlo BlackoutButton que es el que se va a encargar de oscurecer completamente la pantalla.
Ajustamos los tamaños y colores a gusto.
Debemos asegurarnos de que el botón esté por debajo de la imagen en la jerarquía, de esa forma primero se dibujará la pantalla negra y luego el botón, como vemos en la figura 14.
Una vez que configuramos el botón Blackout vamos a duplicarlo y darle el nombre «PauseButton», lo acomodamos donde nos guste en la pantalla. En la figura 16 está mi resultado.
Scripts C#
Ahora vamos a crear dos Scripts C#, el primero lo llamaremos «GameController» y el segundo «UIManager».
El Script GameController lo asignamos al GameObject con el mismo nombre. Podemos seleccionarlo y arrastrarlo al inspector o usar el botón «Add Component».
El Script UIManager lo asignamos al GameObject «UI».
Script GameController
El Script GameController será el que se encargue de indicar cuándo se debe oscurecer la pantalla y en qué valor de opacidad se debe establecer. No se encarga de controlar el objeto imagen directamente, esa será la responsabilidad del UIManager.
GameController tendrá dos funciones, una será la de Blackout que le dirá al UIManager que oscurezca completamente la pantalla y la otra será la función Pausa que hará que la pantalla se oscurezca al 50%.
Campos e Inicialización
Vamos a definir un objeto tipo UIManager para tener la referencia del Script UIManager asignado al GameObject UI y poder así acceder a sus métodos públicos.
También vamos a necesitar dos variables booleanas para indicar si la función de blackout y pausa están habilitadas.
En el método Start encontramos la referencia del Script UIManager asignado al GameObject UI con la instrucción 13 que se observa en la figura 23. Luego ponemos en false las variables booleanas.
Métodos
Para que el Script cumpla las dos funciones que dijimos, vamos a definir dos métodos públicos, uno se llamará «BlackoutFunction» y el otro «Pause». Estos métodos serán ejecutados al pulsar los botones de la interfaz gráfica.
Si querés saber un poco más sobre métodos te invito a leer este artículo que escribí anteriormente, habla sobre qué es un método de manera intuitiva, también hay un video en el canal.
En el método BlackoutFunction lo primero que hacemos es invertir el estado de la variable booleana blackoutActivated, osea que si estaba en false ahora va a ser true y visceversa.
Luego comprobamos el estado de esa variable y vamos a ejecutar un método del Script UIManager con el parámetro apropiado. En este punto aún no hemos escrito el método «SetBlackoutOpacity» de UIManager, así que si escriben las líneas 23 y 27 de la figura 24 van a tener un error.
En el método Pause vamos a hacer lo mismo pero en lugar de oscurecer completamente la pantalla vamos a hacer que se oscurezca a la mitad de opacidad.
Las líneas 23, 27, 37 y 41 podemos escribirlas luego de haber trabajado en el Script UIManager.
Script UIManager
Este Script se va a encargar de controlar los parámetros de la imagen para oscurecer la pantalla.
Para eso va a ejecutar constantemente la función Blackout que se encargará de ir modificando gradualmente la opacidad de la imagen. Además tendrá un método público llamado «SetBlackoutOpacity» que permitirá decirle el nivel de opacidad deseado, 0 significa pantalla negra invisible, 1 es pantalla negra completamente visible.
Campos e Inicialización
Para resolver el comportamiento vamos a necesitar un objeto tipo Image que llamamos «blackoutImage» y que marcaremos con «SerializeField» para que aparezca en el inspector.
Definimos un float llamado «blackoutOpacityChangeStep» para indicar la magnitud de cambio de la opacidad en el tiempo, también lo serializamos. Por último definimos un float llamado «blackoutTargetOpacity» que será el valor al que la opacidad tenderá a acercarse en cada paso de tiempo.
En el método Start hacemos que la opacidad objetivo sea 0. Todo esto podemos verlo en la figura 25.
Métodos
Vamos a definir dos métodos, Blackout privado y SetBlackoutOpacity público. Dentro del método FixedUpdate haremos la llamada al método Blackout, como se observa en la figura 26.
En el método Blackout primero leemos el estado actual de opacidad del objeto imagen (instrucción 29 de la figura 26).
Si la opacidad de ese objeto es menor que la opacidad objetivo haremos que aumente, si la opacidad del objeto es mayor haremos que disminuya. Esto lo conseguimos con el «if» y «else if» de las líneas 31 y 39 respectivamente.
Para que la opacidad aumente o disminuya gradualmente crearemos un nuevo color al que le asignamos las mismas componentes RGB pero al parámetro alfa le sumamos o restamos el float «blackoutOpacityChangeStep». En la figura 26 podemos ver cómo resolver esto.
El método SetBlackoutOpacity será público y tomará como parámetro un valor float. Simplemente asignaremos este valor a la variable «blackoutTargetOpacity», como se observa abajo en la figura 26.
El cambio del valor de opacidad lo hacemos en el método FixedUpdate debido a que no queremos que ocurra instantáneamente sino de manera gradual para tener un efecto Fade In/Out.
Últimos ajustes
Para poder ejecutar los métodos de GameController usando los botones, tenemos que hacerlo en la función OnClick() de la componente botón.
Arrastramos el GameObject GameController al campo debajo de «Runtime Only» y usando el menú desplegable seleccionamos el método «BlackoutFunction».
Si no aparece en esta lista seguramente no lo hemos definido como público.
Con el botón de Pause hacemos lo mismo solo que eligiendo el método Pause de GameController.
Por último seleccionamos el GameObject UI y arrastramos el GameObject BlackoutImage (con la componente imagen, ver figura 12) al campo «Blackout Image». Para el float «BlackoutOpacityChangeStep» ingresamos el valor 0.1.
El resultado se muestra en la figura 29.
Conclusión
En este artículo vimos una forma de oscurecer la pantalla en Unity. Para lograrlo utilizamos una imagen negra y modificamos el valor de Alfa, que determina la opacidad del color. Si el alfa es igual a 1 el color es totalmente opaco, si es igual a 0, el color es totalmente transparente.
Configuramos dos botones para ejecutar métodos públicos del Script GameController, el cual le indica al objeto UIManager cómo debe ser la opacidad de la pantalla negra. UIManager finalmente hace los cambios en el valor de alfa de la pantalla negra.