HoloLens (1.ª generación) y Azure 308: Notificaciones entre dispositivos
Nota
Los tutoriales de Mixed Reality Academy se han diseñado teniendo en cuenta HoloLens (1.ª generación) y los cascos envolventes de realidad mixta. Por lo tanto, creemos que es importante conservar estos tutoriales para los desarrolladores que sigan buscando instrucciones sobre el desarrollo para esos dispositivos. Estos tutoriales no se actualizarán con los conjuntos de herramientas o las interacciones más recientes que se usan para HoloLens 2. Se mantendrán para que sigan funcionando en los dispositivos compatibles. Habrá una nueva serie de tutoriales que se publicarán en el futuro que demostrarán cómo desarrollar para HoloLens 2. Este aviso se actualizará con un vínculo a esos tutoriales cuando se publiquen.
En este curso, aprenderá a agregar funcionalidades de Notification Hubs a una aplicación de realidad mixta mediante Azure Notification Hubs, Azure Tables y Azure Functions.
Azure Notification Hubs es un servicio de Microsoft, que permite a los desarrolladores enviar notificaciones push personalizadas y dirigidas a cualquier plataforma, todas con tecnología dentro de la nube. Esto puede permitir a los desarrolladores comunicarse con los usuarios finales o incluso comunicarse entre varias aplicaciones, en función del escenario. Para más información, visite la página azure Notification Hubs.
Azure Functions es un servicio de Microsoft, que permite a los desarrolladores ejecutar pequeños fragmentos de código, "funciones", en Azure. Esto proporciona una manera de delegar el trabajo en la nube, en lugar de la aplicación local, lo que puede tener muchas ventajas. Azure Functions admite varios lenguajes de desarrollo, como C#, F#, Node.js, Java y PHP. Para más información, visite la página de Azure Functions.
Azure Tables es un servicio en la nube de Microsoft, que permite a los desarrolladores almacenar datos no SQL estructurados en la nube, lo que facilita su acceso a cualquier lugar. El servicio cuenta con un diseño sin esquemas, lo que permite la evolución de las tablas según sea necesario y, por lo tanto, es muy flexible. Para más información, visite la página Tablas de Azure.
Después de completar este curso, tendrá una aplicación de casco envolvente de realidad mixta y una aplicación pc de escritorio, que podrá hacer lo siguiente:
La aplicación pc de escritorio permitirá al usuario mover un objeto en el espacio 2D (X e Y), mediante el mouse.
El movimiento de objetos dentro de la aplicación de PC se enviará a la nube mediante JSON, que estará en forma de cadena, que contiene un identificador de objeto, un tipo y una información de transformación (coordenadas X e Y).
La aplicación de realidad mixta, que tiene una escena idéntica a la aplicación de escritorio, recibirá notificaciones sobre el movimiento de objetos, desde el servicio Notification Hubs (que acaba de actualizar la aplicación pc de escritorio).
Al recibir una notificación, que contendrá el identificador de objeto, el tipo y la información de transformación, la aplicación de realidad mixta aplicará la información recibida a su propia escena.
En la aplicación, es el momento de integrar los resultados con el diseño. Este curso está diseñado para enseñar a integrar un servicio de Azure con el proyecto de Unity. Es su trabajo usar el conocimiento que obtiene de este curso para mejorar la aplicación de realidad mixta. Este curso es un tutorial autocontenida, que no implica directamente ningún otro laboratorio de realidad mixta.
Curso | HoloLens | Cascos envolventes |
---|---|---|
MR y Azure 308: notificaciones entre dispositivos | ✔️ | ✔️ |
Nota
Aunque este curso se centra principalmente en cascos envolventes de Windows Mixed Reality (VR), también puede aplicar lo que aprende en este curso a Microsoft HoloLens. A medida que siga el curso, verá notas sobre los cambios que podría necesitar para admitir HoloLens. Al usar HoloLens, es posible que observe algún eco durante la captura de voz.
Nota
Este tutorial está diseñado para desarrolladores que tienen experiencia básica con Unity y C#. Tenga en cuenta también que los requisitos previos y las instrucciones escritas de este documento representan lo que se ha probado y comprobado en el momento de redactarlo (mayo de 2018). Puede usar el software más reciente, como se muestra en el artículo de instalación de las herramientas , aunque no debe asumirse que la información de este curso coincidirá perfectamente con lo que encontrará en el software más reciente que lo que se muestra a continuación.
Se recomienda el siguiente hardware y software para este curso:
- Un equipo de desarrollo, compatible con Windows Mixed Reality para el desarrollo de cascos envolventes (VR)
- Windows 10 Fall Creators Update (o posterior) con el modo desarrollador habilitado
- El SDK de Windows 10 más reciente
- Unity 2017.4
- Visual Studio 2017
- Casco envolvente (VR) de Windows Mixed Reality o Microsoft HoloLens con el modo desarrollador habilitado
- Acceso a Internet para la configuración de Azure y acceso a Notification Hubs
- Para evitar encontrar problemas al compilar este proyecto, se recomienda encarecidamente crear el proyecto mencionado en este tutorial en una carpeta raíz o casi raíz (las rutas de acceso de carpeta largas pueden causar problemas en tiempo de compilación).
- Debe ser el propietario del Portal para desarrolladores de Microsoft y del Portal de registro de aplicaciones; de lo contrario, no tendrá permiso para acceder a la aplicación en el capítulo 2.
Para usar el servicio Azure Notification Hubs , deberá crear una aplicación en el Portal para desarrolladores de Microsoft, ya que la aplicación deberá registrarse para que pueda enviar y recibir notificaciones.
Inicie sesión en el Portal para desarrolladores de Microsoft.
Tendrá que iniciar sesión en su cuenta Microsoft.
En el panel, haga clic en Crear una nueva aplicación.
Aparecerá un elemento emergente, donde deberá reservar un nombre para la nueva aplicación. En el cuadro de texto, inserte un nombre adecuado; Si el nombre elegido está disponible, aparecerá un tic a la derecha del cuadro de texto. Una vez que haya insertado un nombre disponible, haga clic en el botón Reservar nombre del producto en la parte inferior izquierda del menú emergente.
Con la aplicación creada, ya está listo para pasar al siguiente capítulo.
Inicie sesión en el Portal de registro de aplicaciones, donde se mostrará la nueva aplicación y recupere las credenciales que se usarán para configurar Notification Hubs Service en Azure Portal.
Vaya al Portal de registro de aplicaciones.
Advertencia
Tendrá que usar su cuenta Microsoft para iniciar sesión.
Debe ser la cuenta Microsoft que usó en el capítulo anterior, con el portal para desarrolladores de la Tienda Windows.Encontrará la aplicación en la sección Mis aplicaciones . Una vez que lo haya encontrado, haga clic en él y se le llevará a una nueva página que tiene el nombre de la aplicación más Registro.
Desplácese hacia abajo en la página de registro para encontrar la sección Secretos de aplicación y el SID de paquete de la aplicación. Copie ambos para su uso con la configuración del servicio Azure Notification Hubs en el capítulo siguiente.
Con las credenciales de las aplicaciones recuperadas, deberá ir a Azure Portal, donde creará un servicio Azure Notification Hubs.
Inicie sesión en Azure Portal.
Nota
Si aún no tiene una cuenta de Azure, deberá crear una. Si sigue este tutorial en una situación de clase o laboratorio, pida a su instructor o a uno de los proctores que le ayuden a configurar la nueva cuenta.
Una vez que haya iniciado sesión, haga clic en Nuevo en la esquina superior izquierda y busque Centro de notificaciones y haga clic en Entrar.
Nota
Es posible que la palabra New se haya reemplazado por Create a resource (Crear un recurso) en portales más recientes.
La nueva página proporcionará una descripción del servicio Notification Hubs . En la parte inferior izquierda de este símbolo del sistema, seleccione el botón Crear para crear una asociación con este servicio.
Una vez que haya hecho clic en Crear:
Inserte el nombre deseado para esta instancia de servicio.
Proporcione un espacio de nombres que podrá asociar a esta aplicación.
Seleccione una ubicación.
Elija un grupo de recursos o cree uno nuevo. Un grupo de recursos proporciona una manera de supervisar, controlar el acceso, aprovisionar y administrar la facturación de una colección de recursos de Azure. Se recomienda mantener todos los servicios de Azure asociados a un único proyecto (por ejemplo, estos laboratorios) en un grupo de recursos común).
Si desea obtener más información sobre los grupos de recursos de Azure, siga este vínculo sobre cómo administrar un grupo de recursos.
Seleccione una suscripción adecuada.
También deberá confirmar que ha comprendido los Términos y Condiciones aplicados a este Servicio.
Seleccione Crear.
Una vez que haya hecho clic en Crear, tendrá que esperar a que se cree el servicio, esto puede tardar un minuto.
Aparecerá una notificación en el portal una vez creada la instancia de servicio.
Haga clic en el botón Ir al recurso de la notificación para explorar la nueva instancia de servicio. Se le llevará a la nueva instancia de servicio del Centro de notificaciones.
En la página de información general, a mitad de la página, haga clic en Windows (WNS). El panel de la derecha cambiará para mostrar dos campos de texto, que requieren el SID del paquete y la clave de seguridad, desde la aplicación que configuró anteriormente.
Una vez que haya copiado los detalles en los campos correctos, haga clic en Guardar y recibirá una notificación cuando el Centro de notificaciones se haya actualizado correctamente.
Después de crear la instancia de Notification Hubs Service, vuelva a Azure Portal, donde creará un servicio Azure Tables mediante la creación de un recurso de almacenamiento.
Si aún no ha iniciado sesión, inicie sesión en Azure Portal.
Una vez que haya iniciado sesión, haga clic en Nuevo en la esquina superior izquierda y busque Cuenta de almacenamiento y haga clic en Entrar.
Nota
Es posible que la palabra New se haya reemplazado por Create a resource (Crear un recurso) en portales más recientes.
Seleccione Cuenta de almacenamiento: blob, archivo, tabla, cola en la lista.
La nueva página proporcionará una descripción del servicio de la cuenta de almacenamiento. En la parte inferior izquierda de este símbolo del sistema, seleccione el botón Crear para crear una instancia de este servicio.
Una vez que haya hecho clic en Crear, aparecerá un panel:
Inserte el nombre deseado para esta instancia de servicio (debe estar en minúsculas).
En Modelo de implementación, haga clic en Resource Manager.
En Tipo de cuenta, con el menú desplegable, seleccione Almacenamiento (uso general v1) .
Seleccione una ubicación adecuada.
En el menú desplegable Replicación, seleccione Almacenamiento con redundancia geográfica con acceso de lectura (RA-GRS).
En Rendimiento, haga clic en Estándar.
En la sección Transferencia segura necesaria , seleccione Deshabilitado.
En el menú desplegable Suscripción , seleccione una suscripción adecuada.
Elija un grupo de recursos o cree uno nuevo. Un grupo de recursos proporciona una manera de supervisar, controlar el acceso, aprovisionar y administrar la facturación de una colección de recursos de Azure. Se recomienda mantener todos los servicios de Azure asociados a un único proyecto (por ejemplo, estos laboratorios) en un grupo de recursos común).
Si desea obtener más información sobre los grupos de recursos de Azure, siga este vínculo sobre cómo administrar un grupo de recursos.
Deje Redes virtuales como Deshabilitada si se trata de una opción para usted.
Haga clic en Crear.
Una vez que haya hecho clic en Crear, tendrá que esperar a que se cree el servicio, esto puede tardar un minuto.
Aparecerá una notificación en el portal una vez creada la instancia de servicio. Haga clic en las notificaciones para explorar la nueva instancia de servicio.
Haga clic en el botón Ir al recurso de la notificación para explorar la nueva instancia de servicio. Se le llevará a la nueva página de información general de la instancia del servicio de almacenamiento.
En la página de información general, a la derecha, haga clic en Tablas.
El panel de la derecha cambiará para mostrar la información de Table service , donde debe agregar una nueva tabla. Para ello, haga clic en el + botón Tabla en la esquina superior izquierda.
Se mostrará una nueva página, donde debe escribir un nombre de tabla. Este es el nombre que usará para hacer referencia a los datos de la aplicación en capítulos posteriores. Inserte un nombre adecuado y haga clic en Aceptar.
Una vez creada la nueva tabla, podrá verla en la página Table service (en la parte inferior).
Ahora que se ha configurado la cuenta de almacenamiento de Table service , es hora de agregar datos a ella, que se usarán para almacenar y recuperar información. La edición de las tablas se puede realizar a través de Visual Studio.
Abra Visual Studio.
En el menú, haga clic en Ver>Cloud Explorer.
Cloud Explorer se abrirá como un elemento acoplado (sea paciente, ya que la carga puede tardar tiempo).
Nota
Si la suscripción que usó para crear las cuentas de almacenamiento no está visible, asegúrese de que tiene:
Ha iniciado sesión en la misma cuenta que usó para Azure Portal.
Seleccione la suscripción en la página Administración de cuentas (es posible que tenga que aplicar un filtro desde la configuración de la cuenta):
Se mostrarán los servicios en la nube de Azure. Busque Cuentas de almacenamiento y haga clic en la flecha situada a la izquierda para expandir las cuentas.
Una vez expandido, la cuenta de almacenamiento recién creada debe estar disponible. Haga clic en la flecha situada a la izquierda del almacenamiento y, una vez expandido, busque Tablas y haga clic en la flecha situada junto a ella para mostrar la tabla que creó en el último capítulo. Haga doble clic en la tabla.
La tabla se abrirá en el centro de la ventana de Visual Studio. Haga clic en el icono de tabla con el + (más) en él.
Aparecerá una ventana en la que se le pedirá que agregue entidad. Creará tres entidades en total, cada una con varias propiedades. Observará que ya se proporcionan PartitionKey y RowKey, ya que la tabla los usa para encontrar los datos.
Actualice el valor de PartitionKey y RowKey como se indica a continuación (recuerde hacerlo para cada propiedad de fila que agregue, aunque incremente rowKey cada vez):
Haga clic en Agregar propiedad para agregar filas de datos adicionales. Haga que la primera tabla vacía coincida con la tabla siguiente.
Cuando haya terminado, haga clic en Aceptar.
Advertencia
Asegúrese de que ha cambiado el tipo de las entradas X, Y y Z a Double.
Observará que la tabla ahora tiene una fila de datos. Haga clic de nuevo en el + icono (más) para agregar otra entidad.
Cree una propiedad adicional y, a continuación, establezca los valores de la nueva entidad para que coincidan con los que se muestran a continuación.
Repita el último paso para agregar otra entidad. Establezca los valores de esta entidad en los que se muestran a continuación.
La tabla debería tener ahora un aspecto similar al siguiente.
Ha completado este capítulo. Asegúrese de guardar.
Cree una aplicación de funciones de Azure, a la que llamará la aplicación de escritorio para actualizar Table service y enviar una notificación a través del Centro de notificaciones.
En primer lugar, debe crear un archivo que permita que la función de Azure cargue las bibliotecas que necesita.
Abra el Bloc de notas (presione La tecla de Windows y escriba el Bloc de notas).
Con el Bloc de notas abierto, inserte la estructura JSON siguiente en ella. Una vez hecho esto, guárdelo en el escritorio como project.json. Es importante que la nomenclatura sea correcta: asegúrese de que no tiene una extensión de archivo .txt . Este archivo define las bibliotecas que usará la función, si ha usado NuGet, será familiar.
{ "frameworks": { "net46":{ "dependencies": { "WindowsAzure.Storage": "7.0.0", "Microsoft.Azure.NotificationHubs" : "1.0.9", "Microsoft.Azure.WebJobs.Extensions.NotificationHubs" :"1.1.0" } } } }
Inicie sesión en Azure Portal.
Una vez que haya iniciado sesión, haga clic en Nuevo en la esquina superior izquierda y busque Function App, presione Entrar.
Nota
Es posible que la palabra New se haya reemplazado por Create a resource (Crear un recurso) en portales más recientes.
La nueva página proporcionará una descripción de Function App Service. En la parte inferior izquierda de este símbolo del sistema, seleccione el botón Crear para crear una asociación con este servicio.
Una vez que haya hecho clic en Crear, rellene lo siguiente:
En Nombre de la aplicación, inserte el nombre deseado para esta instancia de servicio.
Seleccione una opción en Suscripción.
Seleccione el plan de tarifa adecuado para usted, si es la primera vez que se crea una instancia de Function App Service, debería estar disponible un nivel gratuito.
Elija un grupo de recursos o cree uno nuevo. Un grupo de recursos proporciona una manera de supervisar, controlar el acceso, aprovisionar y administrar la facturación de una colección de recursos de Azure. Se recomienda mantener todos los servicios de Azure asociados a un único proyecto (por ejemplo, estos laboratorios) en un grupo de recursos común).
Si desea obtener más información sobre los grupos de recursos de Azure, siga este vínculo sobre cómo administrar un grupo de recursos.
Para el sistema operativo, haga clic en Windows, ya que es la plataforma prevista.
Seleccione un plan de hospedaje (este tutorial usa un plan de consumo).
Seleccione una ubicación (elija la misma ubicación que el almacenamiento que ha creado en el paso anterior).
En la sección Almacenamiento , debe seleccionar el servicio de almacenamiento que creó en el paso anterior.
No necesitará Application Insights en esta aplicación, así que no dude en dejarla desactivada.
Haga clic en Crear.
Una vez que haya hecho clic en Crear , tendrá que esperar a que se cree el servicio, esto puede tardar un minuto.
Aparecerá una notificación en el portal una vez creada la instancia de servicio.
Haga clic en las notificaciones para explorar la nueva instancia de servicio.
Haga clic en el botón Ir al recurso de la notificación para explorar la nueva instancia de servicio.
Haga clic en el + icono (más) situado junto a Funciones para crear nuevo.
En el panel central, aparecerá la ventana Creación de funciones. Omita la información de la mitad superior del panel y haga clic en Función personalizada, que se encuentra cerca de la parte inferior (en el área azul, como se muestra a continuación).
La nueva página de la ventana mostrará varios tipos de función. Desplácese hacia abajo para ver los tipos púrpuras y haga clic en ELEMENTO HTTP PUT .
Importante
Es posible que tenga que desplazarse más hacia abajo en la página (y es posible que esta imagen no tenga exactamente el mismo aspecto, si se han realizado actualizaciones de Azure Portal), pero busca un elemento denominado HTTP PUT.
Aparecerá la ventana HTTP PUT , donde debe configurar la función (consulte a continuación la imagen).
En Idioma, en el menú desplegable, seleccione C#.
En Nombre, escriba un nombre adecuado.
En el menú desplegable Nivel de autenticación, seleccione Función.
Para la sección Nombre de tabla, debe usar el nombre exacto que usó para crear el servicio Table service anteriormente (incluido el mismo caso de letra).
En la sección Conexión de la cuenta de almacenamiento, use el menú desplegable y seleccione la cuenta de almacenamiento desde allí. Si no está ahí, haga clic en el hipervínculo Nuevo junto con el título de sección para mostrar otro panel, donde debe aparecer la cuenta de almacenamiento.
Haga clic en Crear y recibirá una notificación de que la configuración se ha actualizado correctamente.
Después de hacer clic en Crear, se le redirigirá al editor de funciones.
Inserte el código siguiente en el editor de funciones (reemplazando el código de la función):
#r "Microsoft.WindowsAzure.Storage" using System; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Table; using Microsoft.Azure.NotificationHubs; using Newtonsoft.Json; public static async Task Run(UnityGameObject gameObj, CloudTable table, IAsyncCollector<Notification> notification, TraceWriter log) { //RowKey of the table object to be changed string rowKey = gameObj.RowKey; //Retrieve the table object by its RowKey TableOperation operation = TableOperation.Retrieve<UnityGameObject>("UnityPartitionKey", rowKey); TableResult result = table.Execute(operation); //Create a UnityGameObject so to set its parameters UnityGameObject existingGameObj = (UnityGameObject)result.Result; existingGameObj.RowKey = rowKey; existingGameObj.X = gameObj.X; existingGameObj.Y = gameObj.Y; existingGameObj.Z = gameObj.Z; //Replace the table appropriate table Entity with the value of the UnityGameObject operation = TableOperation.Replace(existingGameObj); table.Execute(operation); log.Verbose($"Updated object position"); //Serialize the UnityGameObject string wnsNotificationPayload = JsonConvert.SerializeObject(existingGameObj); log.Info($"{wnsNotificationPayload}"); var headers = new Dictionary<string, string>(); headers["X-WNS-Type"] = @"wns/raw"; //Send the raw notification to subscribed devices await notification.AddAsync(new WindowsNotification(wnsNotificationPayload, headers)); log.Verbose($"Sent notification"); } // This UnityGameObject represent a Table Entity public class UnityGameObject : TableEntity { public string Type { get; set; } public double X { get; set; } public double Y { get; set; } public double Z { get; set; } public string RowKey { get; set; } }
Nota
Con las bibliotecas incluidas, la función recibe el nombre y la ubicación del objeto que se movió en la escena de Unity (como un objeto de C#, denominado UnityGameObject). A continuación, este objeto se usa para actualizar los parámetros del objeto dentro de la tabla creada. Después de esto, la función realiza una llamada al servicio del Centro de notificaciones creado, que notifica a todas las aplicaciones suscritas.
Con el código en contexto, haga clic en Guardar.
A continuación, haga clic en el < icono (flecha), en el lado derecho de la página.
Un panel se deslizará desde la derecha. En ese panel, haga clic en Cargar y aparecerá un explorador de archivos.
Vaya a y haga clic en el archivo project.json , que creó anteriormente en el Bloc de notas y, a continuación, haga clic en el botón Abrir . Este archivo define las bibliotecas que usará la función.
Cuando el archivo se haya cargado, aparecerá en el panel de la derecha. Al hacer clic en él, se abrirá en el editor de funciones. Debe tener exactamente el mismo aspecto que la siguiente imagen (en el paso 23 siguiente).
A continuación, en el panel de la izquierda, debajo de Functions, haga clic en el vínculo Integrar .
En la página siguiente, en la esquina superior derecha, haga clic en Editor avanzado (como se muestra a continuación).
Se abrirá un archivo function.json en el panel central, que debe reemplazarse por el siguiente fragmento de código. Esto define la función que está compilando y los parámetros pasados a la función.
{ "bindings": [ { "authLevel": "function", "type": "httpTrigger", "methods": [ "get", "post" ], "name": "gameObj", "direction": "in" }, { "type": "table", "name": "table", "tableName": "SceneObjectsTable", "connection": "mrnothubstorage_STORAGE", "direction": "in" }, { "type": "notificationHub", "direction": "out", "name": "notification", "hubName": "MR_NotHub_ServiceInstance", "connection": "MRNotHubNS_DefaultFullSharedAccessSignature_NH", "platform": "wns" } ] }
El editor debería tener ahora un aspecto similar al de la imagen siguiente:
Es posible que observe que los parámetros de entrada que acaba de insertar podrían no coincidir con los detalles de la tabla y el almacenamiento y, por lo tanto, tendrán que actualizarse con su información. No haga esto aquí, ya que se trata a continuación. Simplemente haga clic en el vínculo Editor estándar , en la esquina superior derecha de la página, para volver.
De nuevo en el editor Estándar, haga clic en Azure Table Storage (tabla) en Entradas.
Asegúrese de que la siguiente coincidencia con su información, ya que pueden ser diferentes (hay una imagen debajo de los pasos siguientes):
Nombre de tabla: el nombre de la tabla que creó en el servicio Azure Storage, Tables.
Conexión de la cuenta de almacenamiento: haga clic en nuevo, que aparece junto con el menú desplegable y aparecerá un panel a la derecha de la ventana.
Seleccione la cuenta de almacenamiento que creó anteriormente para hospedar Las aplicaciones de funciones.
Observará que se ha creado el valor de conexión de la cuenta de almacenamiento.
Asegúrese de presionar Guardar una vez que haya terminado.
La página Entradas debe coincidir ahora con la siguiente, mostrando su información.
A continuación, haga clic en Centro de notificaciones de Azure (notificación): en Salidas. Asegúrese de que la información coincide con la siguiente, ya que puede ser diferente (hay una imagen debajo de los pasos siguientes):
Nombre del centro de notificaciones: este es el nombre de la instancia de servicio del Centro de notificaciones , que creó anteriormente.
Conexión de espacio de nombres de Notification Hubs: haga clic en nuevo, que aparece junto con el menú desplegable.
Aparecerá el elemento emergente Conexión (consulte la imagen siguiente), donde debe seleccionar el espacio de nombres del Centro de notificaciones, que configuró anteriormente.
Seleccione el nombre del Centro de notificaciones en el menú desplegable central.
Establezca el menú desplegable Directiva en DefaultFullSharedAccessSignature.
Haga clic en el botón Seleccionar para volver.
La página Salidas debe coincidir ahora con la siguiente, pero con la información en su lugar. Asegúrese de presionar Guardar.
Advertencia
No edite directamente el nombre del Centro de notificaciones (esto debe hacerse con el Editor avanzado, siempre que siga los pasos anteriores correctamente.
En este momento, debe probar la función para asegurarse de que funciona. Para ello, siga estos pasos:
Vaya a la página de función una vez más:
De nuevo en la página de la función, haga clic en la pestaña Prueba del lado derecho de la página para abrir la hoja Prueba :
En el cuadro de texto Cuerpo de la solicitud de la hoja, pegue el código siguiente:
{ "Type":null, "X":3, "Y":0, "Z":1, "PartitionKey":null, "RowKey":"Obj2", "Timestamp":"0001-01-01T00:00:00+00:00", "ETag":null }
Con el código de prueba implementado, haga clic en el botón Ejecutar situado en la parte inferior derecha y se ejecutará la prueba. Los registros de salida de la prueba aparecerán en el área de consola, debajo del código de función.
Advertencia
Si se produce un error en la prueba anterior, deberá comprobar que ha seguido exactamente los pasos anteriores, especialmente la configuración del panel de integración.
Importante
La aplicación de escritorio que está creando ahora no funcionará en el Editor de Unity. Debe ejecutarse fuera del Editor, siguiendo la compilación de la aplicación mediante Visual Studio (o la aplicación implementada).
A continuación se muestra una configuración típica para desarrollar con Unity y realidad mixta, y como tal, es una buena plantilla para otros proyectos.
Configure y pruebe los cascos envolventes de realidad mixta.
Nota
No necesitará controladores de movimiento para este curso. Si necesita soporte técnico para configurar los auriculares envolventes, siga este vínculo sobre cómo configurar Windows Mixed Reality.
Abra Unity y haga clic en Nuevo.
Debe proporcionar un nombre de proyecto de Unity, insertar UnityDesktopNotifHub. Asegúrese de que el tipo de proyecto esté establecido en 3D. Establezca la ubicación en algún lugar adecuado para usted (recuerde que más cerca de los directorios raíz es mejor). A continuación, haga clic en Crear proyecto.
Con Unity abierto, vale la pena comprobar que el Editor de scripts predeterminado está establecido en Visual Studio. Vaya a Editar>preferencias y, a continuación, en la nueva ventana, vaya a Herramientas externas. Cambie el Editor de scripts externos a Visual Studio 2017. Cierre la ventana Preferencias.
A continuación, vaya a Configuración> de compilación de archivos y seleccione Plataforma universal de Windows y haga clic en el botón Cambiar plataforma para aplicar la selección.
Mientras sigue en Configuración de compilación de archivos>, asegúrese de que:
El dispositivo de destino se establece en Cualquier dispositivo
Esta aplicación será para el escritorio, por lo que debe ser Cualquier dispositivo.
Tipo de compilación se establece en D3D
El SDK se establece en Latest installed (Versión más reciente instalada)
La versión de Visual Studio se establece en Latest installed (Versión más reciente instalada)
Build and Run (Compilar y ejecutar ) está establecido en Equipo local
Aunque aquí, vale la pena guardar la escena y agregarla a la compilación.
Para ello, seleccione Agregar escenas abiertas. Aparecerá una ventana de guardado.
Cree una nueva carpeta para esto y cualquier escena futura y, a continuación, seleccione el botón Nueva carpeta para crear una nueva carpeta, asígnela el nombre Scenes.
Abra la carpeta Escenas recién creada y, a continuación, en el campo Nombre de archivo: texto, escriba NH_Desktop_Scene y presione Guardar.
La configuración restante, en Configuración de compilación, debe dejarse como predeterminada por ahora.
En la misma ventana, haga clic en el botón Configuración del reproductor; se abrirá el panel relacionado en el espacio donde se encuentra el Inspector.
En este panel, es necesario comprobar algunos valores:
En la pestaña Otros valores :
La versión del entorno de ejecución de scripting debe ser experimental (equivalente a .NET 4.6)
El back-end de scripting debe ser .NET
El nivel de compatibilidad de API debe ser .NET 4.6
En la pestaña Configuración de publicación, en Funcionalidades, active:
InternetClient
De nuevo en Configuración de compilación, los proyectos de Unity de C# ya no están atenuados; marque la casilla situada junto a esto.
Cierre la ventana Build Settings (Configuración de compilación).
Guarde la escena y el archivo de>proyecto Guardar escena/Proyecto de guardado de archivos.>
Importante
Si desea omitir el componente Configuración de Unity para este proyecto (Aplicación de escritorio) y continuar directamente en el código, no dude en descargar este paquete .unitypackage, importarlo en el proyecto como paquete personalizado y, a continuación, continuar desde el capítulo 9. Todavía tendrá que agregar los componentes del script.
Usará Azure Storage para Unity (que aprovecha el SDK de .Net para Azure). Para más información, siga este vínculo sobre Azure Storage para Unity.
Actualmente hay un problema conocido en Unity que requiere que los complementos se vuelvan a configurar después de la importación. Estos pasos (4 - 7 en esta sección) ya no serán necesarios después de que se haya resuelto el error.
Para importar el SDK en su propio proyecto, asegúrese de que ha descargado el archivo .unitypackage más reciente de GitHub. A continuación, haga lo siguiente:
Agregue el archivo .unitypackage a Unity mediante la opción de > menú Importar paquete personalizado de paquetes > de activos.
En el cuadro Importar paquete de Unity que aparece, puede seleccionar todo en Almacenamiento de complementos>. Desactive todo lo demás, ya que no es necesario para este curso.
Haga clic en el botón Importar para agregar los elementos al proyecto.
Vaya a la carpeta Storage en Complementos en la vista Proyecto y seleccione solo los complementos siguientes:
- Microsoft.Data.Edm
- Microsoft.Data.OData
- Microsoft.WindowsAzure.Storage
- Newtonsoft.Json
- System.Spatial
Con estos complementos específicos seleccionados, desactive Cualquier plataforma y desactive WSAPlayer y haga clic en Aplicar.
Nota
Estamos marcando estos complementos concretos para que solo se usen en el Editor de Unity. Esto se debe a que hay diferentes versiones de los mismos complementos en la carpeta WSA que se usarán después de exportar el proyecto desde Unity.
En la carpeta Complemento de almacenamiento , seleccione solo:
Microsoft.Data.Services.Client
Active la casilla No procesar en Configuración de la plataforma y haga clic en Aplicar.
Nota
Estamos marcando este complemento "No procesar", porque el parcheador de ensamblados de Unity tiene dificultades para procesar este complemento. El complemento seguirá funcionando aunque no se procese.
Ahora debe crear los scripts que contienen el código para ejecutar esta aplicación.
El primer script que debe crear es TableToScene, que es responsable de:
- Lectura de entidades dentro de la tabla de Azure.
- Con los datos de tabla, determine qué objetos se van a generar y en qué posición.
El segundo script que debe crear es CloudScene, que es responsable de:
- Registrar el evento de clic izquierdo para permitir al usuario arrastrar objetos alrededor de la escena.
- Serialización de los datos del objeto de esta escena de Unity y envío a La aplicación de funciones de Azure.
Para crear esta clase:
Haga clic con el botón derecho en la carpeta de recursos que se encuentra en el Panel de proyectos, Crear>carpeta. Asigne un nombre a la carpeta Scripts.
Haga doble clic en la carpeta que acaba de crear para abrirla.
Haga clic con el botón derecho en la carpeta Scripts y haga clic en Crear>script de C#. Asigne al script el nombre TableToScene.
Haga doble clic en el script para abrirlo en Visual Studio 2017.
Agregue los siguientes espacios de nombres:
using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Auth; using Microsoft.WindowsAzure.Storage.Table; using UnityEngine;
En la clase , inserte las siguientes variables:
/// <summary> /// allows this class to behave like a singleton /// </summary> public static TableToScene instance; /// <summary> /// Insert here you Azure Storage name /// </summary> private string accountName = " -- Insert your Azure Storage name -- "; /// <summary> /// Insert here you Azure Storage key /// </summary> private string accountKey = " -- Insert your Azure Storage key -- ";
Nota
Sustituya el valor accountName por el nombre del servicio de Azure Storage y el valor accountKey por el valor de clave que se encuentra en el servicio Azure Storage, en Azure Portal (consulte la imagen siguiente).
Ahora agregue los métodos Start() y Awake() para inicializar la clase .
/// <summary> /// Triggers before initialization /// </summary> void Awake() { // static instance of this class instance = this; } /// <summary> /// Use this for initialization /// </summary> void Start() { // Call method to populate the scene with new objects as // pecified in the Azure Table PopulateSceneFromTableAsync(); }
En la clase TableToScene , agregue el método que recuperará los valores de la tabla de Azure y los usará para generar los primitivos adecuados en la escena.
/// <summary> /// Populate the scene with new objects as specified in the Azure Table /// </summary> private async void PopulateSceneFromTableAsync() { // Obtain credentials for the Azure Storage StorageCredentials creds = new StorageCredentials(accountName, accountKey); // Storage account CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true); // Storage client CloudTableClient client = account.CreateCloudTableClient(); // Table reference CloudTable table = client.GetTableReference("SceneObjectsTable"); TableContinuationToken token = null; // Query the table for every existing Entity do { // Queries the whole table by breaking it into segments // (would happen only if the table had huge number of Entities) TableQuerySegment<AzureTableEntity> queryResult = await table.ExecuteQuerySegmentedAsync(new TableQuery<AzureTableEntity>(), token); foreach (AzureTableEntity entity in queryResult.Results) { GameObject newSceneGameObject = null; Color newColor; // check for the Entity Type and spawn in the scene the appropriate Primitive switch (entity.Type) { case "Cube": // Create a Cube in the scene newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Cube); newColor = Color.blue; break; case "Sphere": // Create a Sphere in the scene newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere); newColor = Color.red; break; case "Cylinder": // Create a Cylinder in the scene newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Cylinder); newColor = Color.yellow; break; default: newColor = Color.white; break; } newSceneGameObject.name = entity.RowKey; newSceneGameObject.GetComponent<MeshRenderer>().material = new Material(Shader.Find("Diffuse")) { color = newColor }; //check for the Entity X,Y,Z and move the Primitive at those coordinates newSceneGameObject.transform.position = new Vector3((float)entity.X, (float)entity.Y, (float)entity.Z); } // if the token is null, it means there are no more segments left to query token = queryResult.ContinuationToken; } while (token != null); }
Fuera de la clase TableToScene , debe definir la clase usada por la aplicación para serializar y deserializar las entidades de tabla.
/// <summary> /// This objects is used to serialize and deserialize the Azure Table Entity /// </summary> [System.Serializable] public class AzureTableEntity : TableEntity { public AzureTableEntity(string partitionKey, string rowKey) : base(partitionKey, rowKey) { } public AzureTableEntity() { } public string Type { get; set; } public double X { get; set; } public double Y { get; set; } public double Z { get; set; } }
Asegúrese de guardar antes de volver al Editor de Unity.
Haga clic en la Cámara principal en el panel Jerarquía para que sus propiedades aparezcan en el Inspector.
Con la carpeta Scripts abierta, seleccione el archivo TableToScene de script y arrástrelo a la cámara principal. El resultado debe ser el siguiente:
El segundo script que debe crear es CloudScene, que es responsable de:
Registrar el evento de clic izquierdo para permitir al usuario arrastrar objetos alrededor de la escena.
Serialización de los datos del objeto de esta escena de Unity y envío a La aplicación de funciones de Azure.
Para crear el segundo script:
Haga clic con el botón derecho en la carpeta Scripts , haga clic en Crear, Script de C#. Asigne al script el nombre CloudScene.
Agregue los siguientes espacios de nombres:
using Newtonsoft.Json; using System.Collections; using System.Text; using System.Threading.Tasks; using UnityEngine; using UnityEngine.Networking;
Inserte las siguientes variables:
/// <summary> /// Allows this class to behave like a singleton /// </summary> public static CloudScene instance; /// <summary> /// Insert here you Azure Function Url /// </summary> private string azureFunctionEndpoint = "--Insert here you Azure Function Endpoint--"; /// <summary> /// Flag for object being moved /// </summary> private bool gameObjHasMoved; /// <summary> /// Transform of the object being dragged by the mouse /// </summary> private Transform gameObjHeld; /// <summary> /// Class hosted in the TableToScene script /// </summary> private AzureTableEntity azureTableEntity;
Sustituya el valor azureFunctionEndpoint por la dirección URL de la aplicación de funciones de Azure que se encuentra en Azure Function App Service, en Azure Portal, como se muestra en la imagen siguiente:
Ahora agregue los métodos Start() y Awake() para inicializar la clase .
/// <summary> /// Triggers before initialization /// </summary> void Awake() { // static instance of this class instance = this; } /// <summary> /// Use this for initialization /// </summary> void Start() { // initialise an AzureTableEntity azureTableEntity = new AzureTableEntity(); }
En el método Update(), agregue el código siguiente que detectará la entrada del mouse y arrastrará, que a su vez moverá GameObjects en la escena. Si el usuario ha arrastrado y quitado un objeto, pasará el nombre y las coordenadas del objeto al método UpdateCloudScene(), que llamará al servicio Azure Function App, que actualizará la tabla de Azure y desencadenará la notificación.
/// <summary> /// Update is called once per frame /// </summary> void Update() { //Enable Drag if button is held down if (Input.GetMouseButton(0)) { // Get the mouse position Vector3 mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10); Vector3 objPos = Camera.main.ScreenToWorldPoint(mousePosition); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; // Raycast from the current mouse position to the object overlapped by the mouse if (Physics.Raycast(ray, out hit)) { // update the position of the object "hit" by the mouse hit.transform.position = objPos; gameObjHasMoved = true; gameObjHeld = hit.transform; } } // check if the left button mouse is released while holding an object if (Input.GetMouseButtonUp(0) && gameObjHasMoved) { gameObjHasMoved = false; // Call the Azure Function that will update the appropriate Entity in the Azure Table // and send a Notification to all subscribed Apps Debug.Log("Calling Azure Function"); StartCoroutine(UpdateCloudScene(gameObjHeld.name, gameObjHeld.position.x, gameObjHeld.position.y, gameObjHeld.position.z)); } }
Ahora agregue el método UpdateCloudScene(), como se indica a continuación:
private IEnumerator UpdateCloudScene(string objName, double xPos, double yPos, double zPos) { WWWForm form = new WWWForm(); // set the properties of the AzureTableEntity azureTableEntity.RowKey = objName; azureTableEntity.X = xPos; azureTableEntity.Y = yPos; azureTableEntity.Z = zPos; // Serialize the AzureTableEntity object to be sent to Azure string jsonObject = JsonConvert.SerializeObject(azureTableEntity); using (UnityWebRequest www = UnityWebRequest.Post(azureFunctionEndpoint, jsonObject)) { byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(jsonObject); www.uploadHandler = new UploadHandlerRaw(jsonToSend); www.uploadHandler.contentType = "application/json"; www.downloadHandler = new DownloadHandlerBuffer(); www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); string response = www.responseCode.ToString(); } }
Guardar el código y volver a Unity
Arrastre el script CloudScene a la cámara principal.
Haga clic en la Cámara principal en el panel Jerarquía para que sus propiedades aparezcan en el Inspector.
Con la carpeta Scripts abierta, seleccione el script CloudScene y arrástrelo a la cámara principal. El resultado debe ser el siguiente:
Ahora se ha completado todo lo necesario para la sección unity de este proyecto.
Vaya a Configuración de compilación (Configuración de compilación de archivos>).
En la ventana Configuración de compilación, haga clic en Compilar.
Aparecerá una ventana Explorador de archivos, que le pedirá una ubicación en Compilar. Cree una nueva carpeta (haciendo clic en Nueva carpeta en la esquina superior izquierda) y asígnela el nombre BUILDS.
Abra la nueva carpeta BUILDS y cree otra carpeta (con Nueva carpeta una vez más) y asígnela el nombre NH_Desktop_App.
Con el NH_Desktop_App seleccionado. Haga clic en Seleccionar carpeta. El proyecto tardará un minuto en compilarse.
Después de la compilación, Explorador de archivos aparecerá en la que se muestra la ubicación del nuevo proyecto. Sin embargo, no es necesario abrirlo, ya que necesita crear primero el otro proyecto de Unity, en los siguientes capítulos.
A continuación se muestra una configuración típica para desarrollar con la realidad mixta y, como tal, es una buena plantilla para otros proyectos.
Abra Unity y haga clic en Nuevo.
Ahora deberá proporcionar un nombre de proyecto de Unity, insertar UnityMRNotifHub. Asegúrese de que el tipo de proyecto esté establecido en 3D. Establezca la ubicación en algún lugar adecuado para usted (recuerde que más cerca de los directorios raíz es mejor). A continuación, haga clic en Crear proyecto.
Con Unity abierto, vale la pena comprobar que el Editor de scripts predeterminado está establecido en Visual Studio. Vaya a Editar>preferencias y, a continuación, en la nueva ventana, vaya a Herramientas externas. Cambie el Editor de scripts externos a Visual Studio 2017. Cierre la ventana Preferencias.
A continuación, vaya a Configuración> de compilación de archivos y cambie la plataforma a Plataforma universal de Windows haciendo clic en el botón Cambiar plataforma.
Vaya a Configuración de compilación de archivos>y asegúrese de que:
El dispositivo de destino se establece en Cualquier dispositivo
Para Microsoft HoloLens, establezca Dispositivo de destino en HoloLens.
Tipo de compilación se establece en D3D
El SDK se establece en Latest installed (Versión más reciente instalada)
La versión de Visual Studio se establece en Latest installed (Versión más reciente instalada)
Build and Run (Compilar y ejecutar ) está establecido en Equipo local
Aunque aquí, vale la pena guardar la escena y agregarla a la compilación.
Para ello, seleccione Agregar escenas abiertas. Aparecerá una ventana de guardado.
Cree una nueva carpeta para esto y cualquier escena futura y, a continuación, seleccione el botón Nueva carpeta para crear una nueva carpeta, asígnela el nombre Scenes.
Abra la carpeta Escenas recién creada y, a continuación, en el campo Nombre de archivo: texto, escriba NH_MR_Scene y presione Guardar.
La configuración restante, en Configuración de compilación, debe dejarse como predeterminada por ahora.
En la misma ventana, haga clic en el botón Configuración del reproductor; se abrirá el panel relacionado en el espacio donde se encuentra el Inspector.
En este panel, es necesario comprobar algunos valores:
En la pestaña Otros valores :
La versión del entorno de ejecución de scripting debe ser experimental (equivalente a .NET 4.6)
El back-end de scripting debe ser .NET
El nivel de compatibilidad de API debe ser .NET 4.6
Más abajo en el panel, en Configuración de XR (que se encuentra a continuación de Configuración de publicación), marque Virtual Reality Supported (Realidad virtual compatible), asegúrese de que se agrega el SDK de Windows Mixed Reality.
En la pestaña Configuración de publicación, en Funcionalidades, active:
InternetClient
De nuevo en Configuración de compilación, los proyectos de C# de Unity ya no están atenuados: marque la casilla situada junto a esto.
Con estos cambios realizados, cierre la ventana Configuración de compilación.
Guarde la escena y el archivo de>proyecto Guardar escena/Proyecto de guardado de archivos.>
Importante
Si desea omitir el componente Configurar unity para este proyecto (aplicación de realidad mixta) y continuar directamente en el código, no dude en descargar este paquete .unitypackage, importarlo en el proyecto como un paquete personalizado y, a continuación, continuar desde el capítulo 14. Todavía tendrá que agregar los componentes del script.
Usará la biblioteca de Azure Storage para Unity (que usa el SDK de .Net para Azure). Siga este vínculo sobre cómo usar Azure Storage con Unity. Actualmente hay un problema conocido en Unity que requiere que los complementos se vuelvan a configurar después de la importación. Estos pasos (4 - 7 en esta sección) ya no serán necesarios después de que se haya resuelto el error.
Para importar el SDK en su propio proyecto, asegúrese de que ha descargado el archivo .unitypackage más reciente. A continuación, haga lo siguiente:
Agregue el paquete .unitypackage que descargó de lo anterior a Unity mediante la opción de menú Importar>paquete personalizado de activos.>
En el cuadro Importar paquete de Unity que aparece, puede seleccionar todo en Almacenamiento de complementos>.
Haga clic en el botón Importar para agregar los elementos al proyecto.
Vaya a la carpeta Storage en Complementos en la vista Proyecto y seleccione solo los complementos siguientes:
- Microsoft.Data.Edm
- Microsoft.Data.OData
- Microsoft.WindowsAzure.Storage
- Newtonsoft.Json
- System.Spatial
Con estos complementos específicos seleccionados, desactive Cualquier plataforma y desactive WSAPlayer y haga clic en Aplicar.
Nota
Está marcando estos complementos concretos para que solo se usen en el Editor de Unity. Esto se debe a que hay diferentes versiones de los mismos complementos en la carpeta WSA que se usarán después de exportar el proyecto desde Unity.
En la carpeta Complemento de almacenamiento , seleccione solo:
Microsoft.Data.Services.Client
Active la casilla No procesar en Configuración de la plataforma y haga clic en Aplicar.
Nota
Está marcando este complemento "No procesar" porque el parcheador de ensamblados de Unity tiene dificultades para procesar este complemento. El complemento seguirá funcionando aunque no se procese.
La clase TableToScene es idéntica a la que se explica en el capítulo 9. Cree la misma clase en el proyecto de Unity de realidad mixta siguiendo el mismo procedimiento que se explica en el capítulo 9.
Una vez completado este capítulo, ambos proyectos de Unity tendrán esta clase configurada en la cámara principal.
El segundo script que debe crear es NotificationReceiver, que es responsable de:
- Registrar la aplicación con el Centro de notificaciones en la inicialización.
- Escuchando notificaciones procedentes del Centro de notificaciones.
- Deserializar los datos del objeto de las notificaciones recibidas.
- Mueva gameObjects en la escena, en función de los datos deserializados.
Para crear el script NotificationReceiver :
Haga clic con el botón derecho en la carpeta Scripts , haga clic en Crear, Script de C#. Asigne al script el nombre NotificationReceiver.
Haga doble clic en el script para abrirlo.
Agregue los siguientes espacios de nombres:
//using Microsoft.WindowsAzure.Messaging; using Newtonsoft.Json; using System; using System.Collections; using UnityEngine; #if UNITY_WSA_10_0 && !UNITY_EDITOR using Windows.Networking.PushNotifications; #endif
Inserte las siguientes variables:
/// <summary> /// allows this class to behave like a singleton /// </summary> public static NotificationReceiver instance; /// <summary> /// Value set by the notification, new object position /// </summary> Vector3 newObjPosition; /// <summary> /// Value set by the notification, object name /// </summary> string gameObjectName; /// <summary> /// Value set by the notification, new object position /// </summary> bool notifReceived; /// <summary> /// Insert here your Notification Hub Service name /// </summary> private string hubName = " -- Insert the name of your service -- "; /// <summary> /// Insert here your Notification Hub Service "Listen endpoint" /// </summary> private string hubListenEndpoint = "-Insert your Notification Hub Service Listen endpoint-";
Sustituya el valor hubName por el nombre del servicio del centro de notificaciones y el valor hubListenEndpoint por el valor de punto de conexión que se encuentra en la pestaña Directivas de acceso, Azure Notification Hub Service, en Azure Portal (consulte la imagen siguiente).
Ahora agregue los métodos Start() y Awake() para inicializar la clase .
/// <summary> /// Triggers before initialization /// </summary> void Awake() { // static instance of this class instance = this; } /// <summary> /// Use this for initialization /// </summary> void Start() { // Register the App at launch InitNotificationsAsync(); // Begin listening for notifications StartCoroutine(WaitForNotification()); }
Agregue el método WaitForNotification para permitir que la aplicación reciba notificaciones de la biblioteca del centro de notificaciones sin entrar en conflicto con el subproceso principal:
/// <summary> /// This notification listener is necessary to avoid clashes /// between the notification hub and the main thread /// </summary> private IEnumerator WaitForNotification() { while (true) { // Checks for notifications each second yield return new WaitForSeconds(1f); if (notifReceived) { // If a notification is arrived, moved the appropriate object to the new position GameObject.Find(gameObjectName).transform.position = newObjPosition; // Reset the flag notifReceived = false; } } }
El método siguiente, InitNotificationAsync(), registrará la aplicación con el servicio del centro de notificaciones en la inicialización. El código se comenta, ya que Unity no podrá compilar el proyecto. Quitará los comentarios al importar el paquete Nuget de mensajería de Azure en Visual Studio.
/// <summary> /// Register this application to the Notification Hub Service /// </summary> private async void InitNotificationsAsync() { // PushNotificationChannel channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); // NotificationHub hub = new NotificationHub(hubName, hubListenEndpoint); // Registration result = await hub.RegisterNativeAsync(channel.Uri); // If registration was successful, subscribe to Push Notifications // if (result.RegistrationId != null) // { // Debug.Log($"Registration Successful: {result.RegistrationId}"); // channel.PushNotificationReceived += Channel_PushNotificationReceived; // } }
El controlador siguiente, Channel_PushNotificationReceived(), se desencadenará cada vez que se reciba una notificación. Deserializará la notificación, que será la entidad de tabla de Azure que se ha movido en la aplicación de escritorio y, a continuación, moverá el GameObject correspondiente en la escena de MR a la misma posición.
Importante
El código se comenta porque el código hace referencia a la biblioteca de mensajería de Azure, que agregará después de compilar el proyecto de Unity mediante el Administrador de paquetes de Nuget, dentro de Visual Studio. Por lo tanto, el proyecto de Unity no podrá compilarse, a menos que se convierta en comentario. Tenga en cuenta que debe compilar el proyecto y, a continuación, desea volver a Unity, deberá volver a comentar ese código.
///// <summary> ///// Handler called when a Push Notification is received ///// </summary> //private void Channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args) //{ // Debug.Log("New Push Notification Received"); // // if (args.NotificationType == PushNotificationType.Raw) // { // // Raw content of the Notification // string jsonContent = args.RawNotification.Content; // // // Deserialise the Raw content into an AzureTableEntity object // AzureTableEntity ate = JsonConvert.DeserializeObject<AzureTableEntity>(jsonContent); // // // The name of the Game Object to be moved // gameObjectName = ate.RowKey; // // // The position where the Game Object has to be moved // newObjPosition = new Vector3((float)ate.X, (float)ate.Y, (float)ate.Z); // // // Flag thats a notification has been received // notifReceived = true; // } //}
Recuerde guardar los cambios antes de volver al Editor de Unity.
Haga clic en la Cámara principal en el panel Jerarquía para que sus propiedades aparezcan en el Inspector.
Con la carpeta Scripts abierta, seleccione el script NotificationReceiver y arrástrelo a la cámara principal. El resultado debe ser el siguiente:
Nota
Si va a desarrollar esto para Microsoft HoloLens, deberá actualizar el componente Cámara principal, de modo que:
- Borrar marcas: Color sólido
- Fondo: Negro
Este capítulo es idéntico al proceso de compilación del proyecto anterior. Todo lo necesario para la sección Unity de este proyecto ya se ha completado, por lo que es el momento de compilarlo desde Unity.
Vaya a Configuración de compilación ( Configuración de compilación del archivo>).
En el menú Configuración de compilación, asegúrese de que Unity C# Projects* está marcado (lo que le permitirá editar los scripts de este proyecto, después de la compilación).
Una vez hecho esto, haga clic en Compilar.
Aparecerá una ventana Explorador de archivos, que le pedirá una ubicación en Compilar. Cree una nueva carpeta (haciendo clic en Nueva carpeta en la esquina superior izquierda) y asígnela el nombre BUILDS.
Abra la nueva carpeta BUILDS y cree otra carpeta (con Nueva carpeta una vez más) y asígnela el nombre NH_MR_App.
Con el NH_MR_App seleccionado. Haga clic en Seleccionar carpeta. El proyecto tardará un minuto en compilarse.
Después de la compilación, se abrirá una ventana de Explorador de archivos en la ubicación del nuevo proyecto.
Advertencia
Recuerde que, una vez que agregue los siguientes paquetes NuGet (y quite la marca de comentario del código en el capítulo siguiente), el código, cuando se vuelva a abrir en el proyecto de Unity, presentará errores. Si desea volver atrás y continuar editando en el Editor de Unity, necesitará comentar ese código de errosome y, a continuación, quitar la marca de comentario más adelante, una vez que vuelva a trabajar en Visual Studio.
Una vez completada la compilación de realidad mixta, vaya al proyecto de realidad mixta, que ha compilado y haga doble clic en el archivo de solución (.sln) dentro de esa carpeta, para abrir la solución con Visual Studio 2017. Ahora deberá agregar el paquete NuGet WindowsAzure.Messaging.managed ; se trata de una biblioteca que se usa para recibir notificaciones del Centro de notificaciones.
Para importar el paquete NuGet:
En el Explorador de soluciones, haga clic con el botón derecho en la solución.
Haga clic en Administrar paquetes NuGet.
Seleccione la pestaña Examinar y busque WindowsAzure.Messaging.managed.
Seleccione el resultado (como se muestra a continuación) y, en la ventana situada a la derecha, active la casilla situada junto a Project. Esto colocará un tic en la casilla situada junto a Project, junto con la casilla situada junto al proyecto Assembly-CSharp y UnityMRNotifHub .
Es posible que la versión proporcionada inicialmente no sea compatible con este proyecto. Por lo tanto, haga clic en el menú desplegable situado junto a Versión y haga clic en Versión 0.1.7.9 y, a continuación, haga clic en Instalar.
Ya ha terminado de instalar el paquete NuGet. Busque el código comentado que escribió en la clase NotificationReceiver y quite los comentarios.
Después de agregar los paquetes NuGet, deberá quitar la marca de comentario de parte del código dentro de la clase NotificationReceiver .
Esto incluye:
Espacio de nombres en la parte superior:
using Microsoft.WindowsAzure.Messaging;
Todo el código del método InitNotificationsAsync():
/// <summary> /// Register this application to the Notification Hub Service /// </summary> private async void InitNotificationsAsync() { PushNotificationChannel channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); NotificationHub hub = new NotificationHub(hubName, hubListenEndpoint); Registration result = await hub.RegisterNativeAsync(channel.Uri); // If registration was successful, subscribe to Push Notifications if (result.RegistrationId != null) { Debug.Log($"Registration Successful: {result.RegistrationId}"); channel.PushNotificationReceived += Channel_PushNotificationReceived; } }
Advertencia
El código anterior tiene un comentario en él: asegúrese de que no ha quitado accidentalmente la marca de comentario de ese comentario (ya que el código no se compilará si lo tiene).
Y, por último, el evento Channel_PushNotificationReceived :
/// <summary> /// Handler called when a Push Notification is received /// </summary> private void Channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args) { Debug.Log("New Push Notification Received"); if (args.NotificationType == PushNotificationType.Raw) { // Raw content of the Notification string jsonContent = args.RawNotification.Content; // Deserialize the Raw content into an AzureTableEntity object AzureTableEntity ate = JsonConvert.DeserializeObject<AzureTableEntity>(jsonContent); // The name of the Game Object to be moved gameObjectName = ate.RowKey; // The position where the Game Object has to be moved newObjPosition = new Vector3((float)ate.X, (float)ate.Y, (float)ate.Z); // Flag thats a notification has been received notifReceived = true; } }
Con estos comentarios no recomendados, asegúrese de guardar y, a continuación, continúe con el siguiente capítulo.
Ahora debe asociar el proyecto de realidad mixta a la aplicación de la Tienda en la que creó al principio del laboratorio.
Abre la solución.
Haga clic con el botón derecho en el proyecto de aplicación para UWP en el panel de Explorador de soluciones, vaya a La Tienda y Asociar aplicación a la Tienda....
Aparecerá una nueva ventana denominada Asociar la aplicación a la Tienda Windows. Haga clic en Next.
Cargará todas las aplicaciones asociadas a la cuenta en la que ha iniciado sesión. Si no ha iniciado sesión en su cuenta, puede iniciar sesión en esta página.
Busque el nombre de la aplicación de la Tienda que creó al principio de este tutorial y selecciónelo. A continuación, haga clic en Siguiente.
Haga clic en Asociar.
La aplicación ahora está asociada a la aplicación de la Tienda. Esto es necesario para habilitar las notificaciones.
Este capítulo puede ser más fácil con dos personas, ya que el resultado incluirá ambas aplicaciones que se ejecutan, una que se ejecuta en el escritorio del equipo y la otra dentro de los cascos envolventes.
La aplicación de auriculares envolventes está esperando recibir cambios en la escena (cambios de posición de gameObjects locales) y la aplicación de escritorio realizará cambios en su escena local (cambios de posición), que se compartirán en la aplicación mr. Tiene sentido implementar primero la aplicación mr, seguida de la aplicación de escritorio, para que el receptor pueda empezar a escuchar.
Para implementar la aplicación UnityMRNotifHub en la máquina local:
Abra el archivo de solución de la aplicación UnityMRNotifHub en Visual Studio 2017.
En la Plataforma de soluciones, seleccione x86, Máquina local.
En Configuración de la solución, seleccione Depurar.
Vaya al menú Compilar y haga clic en Implementar solución para transferir localmente la aplicación a la máquina.
La aplicación debería aparecer ahora en la lista de aplicaciones instaladas, lista para iniciarse.
Para implementar la aplicación UnityDesktopNotifHub en la máquina local:
Abra el archivo de solución de la aplicación UnityDesktopNotifHub en Visual Studio 2017.
En la Plataforma de soluciones, seleccione x86, Máquina local.
En Configuración de la solución, seleccione Depurar.
Vaya al menú Compilar y haga clic en Implementar solución para transferir localmente la aplicación a la máquina.
La aplicación debería aparecer ahora en la lista de aplicaciones instaladas, lista para iniciarse.
Inicie la aplicación de realidad mixta, seguida de la aplicación escritorio.
Con ambas aplicaciones en ejecución, mueva un objeto en la escena de escritorio (mediante el botón izquierdo del mouse). Estos cambios posicionales se realizarán localmente, serializados y se enviarán a Function App Service. A continuación, Function App Service actualizará la tabla junto con el Centro de notificaciones. Después de recibir una actualización, el Centro de notificaciones enviará los datos actualizados directamente a todas las aplicaciones registradas (en este caso, la aplicación de auriculares inmersivos), que deserializará los datos entrantes y aplicará los nuevos datos posicionales a los objetos locales, moviéndolos en la escena.
Enhorabuena, ha creado una aplicación de realidad mixta que aprovecha Azure Notification Hubs Service y permite la comunicación entre aplicaciones.
¿Puedes averiguar cómo cambiar el color de gameObjects y enviar esa notificación a otras aplicaciones que ven la escena?
¿Puedes agregar movimiento de GameObjects a la aplicación de MR y ver la escena actualizada en la aplicación de escritorio?