Marcos Jesús Barrios Lorenzo
alu0101056944
Un plano a modo de suelo contiene otro plano más pequeño sobre el que se renderiza la salida de la webcam en tiempo real. Nada más ejecutarse se activa la webcam predeterminada. La interfaz contiene un botón para grabar audio del micrófono al pulsarlo, otro para dejar de grabar el micrófono y un último para reproducir la última grabación de audio del micrófono. No se realizó la parte opcional de parar y/o reanudar el video de la webcam. Se puede cambiar el micrófono a utilizar mediante otro botón, que muestra una lista donde se puede elegir el micrófono.
Para implementar la GUI no se utilizó el sistema tradicional de Unity UI sino el sistema más reciente, también totalmente integrado de manera oficial, UI Toolkit. Debido a ello la forma en la que se interactúa con la interfaz es distinta a la habitual. Es por ello que la parte lógica de la interfaz se ha implementado completamente por scripts. En concreto cada botón invoca el método Button.RegisterCallback() que invoca a su vez el callback pasado como argumento cada vez que el EventDispatcher lo proceda.
Se ha utilizado la UI Builder de Unity UI Toolkit para construir la interfaz. El uso de UI Toolkit requirió la descarga de los paquetes com.unity.ui
, com.unity.ui.builder
y la inclusión de sentencias using UnityEngine.UIElements;
en los scripts.
En total se han utilizado tres scripts. El primero, src/CaptureCamera.cs se encarga de renderizar la cámara en el material del plano pequeño. Para ello crea un WebCamTexture y lo asigna a la propiedad material del renderer. Después, src/UIMicrophoneController.cs, que está en un objeto vacío con un componente AudioSource, obtiene referencias a los botones encargados de grabar, dejar de grabar y reproducir sonidos del micrófono. Esas referencias son utilizadas para asignarles callbacks por Button.RegisterCallback(). El callback de grabar utiliza Microphone.Start()
, el de dejar de grabar utiliza Microphone.End()
y finalmente el de reproducir invoca al AudioSource para que reproduzca el sonido.
Finalmente, se agregó un script src/UIDeviceSelector.cs al objeto encargado de la GUI para implementar la funcionalidad que permita elegir el micrófono a utilizar. Se toma ventaja de que los métodos de Microphone sean estáticos. Su funcionamiento consiste en obtener acceso a los elementos de la UI, asignar un callback al botón que muestra la lista de micrófonos y otro callback para las etiquetas que contiene esa lista, de forma que cada vez que se clickee se cambie una variable estática con el nombre del micrófono activo. El objetivo es que esa variable sea utilizada por el resto de scripts para saber qué micrófono utilizar.
Para la UI se ha elegido UIToolkit, una alternativa oficial a la tradicional UnityUI. Utiliza árboles con elementos visuales que forman una jerarquía y ofrece la posibilidad de modificar el estilo mediante ficheros USS, parecidos a CSS.
Su uso ha requerido importar los paquetes com.unity.ui
y com.unity.ui.builder
, éste último para conseguir el editor UIBuilder. Una vez instalado se puede trabajar con todo lo que ofrece UIToolkit en los scripts, cuya clase principal es Unity API: VisualElement, que permite modificar el estilo visual, el layout y utilizar eventos. Todos los elementos de UI son de tipo VisualElement.
El acceso a los elementos del visual tree (Unity Manual: Visual tree) puede resultar confuso. Primero se necesita una referencia al elemento visual raíz (rootVisualElement) contenido en el UIDocument, que es el componente necesario para la UI en UIToolkit y que conecta elementos visuales con GameObjects.
var rootVisualElement = GetComponent<UIDocument>().rootVisualElement;
Con esa referencia se puede acceder a cualquier elemento visual en el visual tree y que en esta práctica utilizado para acceder al método VisualElement.Q<>.
var playButton = rootVisualElement.Q<Button>("play-button");
El método permite hacer una consulta pasando el nombre del elemento visual a encontrar. Su funcionamiento consiste en llamar a Query.Build().First()
, que utiliza un objeto fábrica para construir un QueryState con las reglas de selección de la consulta. Sobre éste se puede llamar al método First() que devuelve el primer VisualElement
que cumple los criterios que almacena.
En este caso se consultan los elementos visuales Button
que tienen en su propiedad name
el string "play-button". Nota: la propiedad name
solo está presente en los VisualElement
extendidos por el paquete com.unity.ui
y, por lo tanto, no aparece en la API de Unity. Ver UIToolkit API: VisualElement.name