Cómo crear un juego de RA con la Fundación de RA de Unity

1. Descripción general

ARCore es el framework de Google para crear experiencias de realidad aumentada en smartphones. Puedes usar AR Foundation de Unity para crear aplicaciones de RA multiplataforma.

Qué compilarás

En este codelab, compilarás un juego simple con AR Foundation. El objetivo del juego es recolectar paquetes en un automóvil que tú controlas con tu dispositivo de mano.

Sin embargo, esto no sucederá en un mundo completamente virtual. Combinarás átomos físicos y bits digitales para crear un juego que comprenda el entorno que lo rodea y con el objetivo de crear un nuevo tipo de experiencia para los jugadores.

Al final de este codelab, tu juego podrá hacer lo siguiente:

  • Detecta aviones del mundo real y trazar un campo de juego sobre ellos.
  • Lanza rayos desde el campo visual de la cámara y detecta intersecciones con aviones.
  • Reacciona a condiciones de iluminación del mundo real para darle al juego más realismo.

Qué aprenderás

  • Cómo configurar un proyecto que use AR Foundation de Unity
  • Cómo usar ARPlaneManager para suscribirse a aviones nuevos
  • Cómo usar Raycast para encontrar intersecciones con geometría virtual
  • Cómo usar ARLightEstimationData para iluminar la escena

Requisitos

2. Configura tu entorno de desarrollo

En este paso, prepararás tu entorno para el desarrollo con AR Foundation de Unity.

Asegúrate de que tu dispositivo sea compatible con la RA

Las experiencias de RA en dispositivos Android se basan en ARCore, que está disponible en dispositivos compatibles con ARCore. Asegúrate de que tu dispositivo de desarrollo sea compatible con RA. Como alternativa, puedes usar una instancia de Android Emulator compatible con RA configurada correctamente.

Cómo configurar la depuración por USB en tu dispositivo

Deberás habilitar las Opciones para desarrolladores en el dispositivo para ejecutar las apps de depuración. Si aún no lo hiciste, consulta la documentación de Android sobre Cómo habilitar las opciones para desarrolladores y la depuración por USB.

Instala Unity (2020.3 LTS)

En tu estación de trabajo, instala Unity 2020 LTS. En este codelab, las capturas de pantalla se muestran de la IU de Unity en la versión 2020.3 (LTS). Es posible que otras versiones de Unity funcionen, pero que requieran pasos adicionales. Es posible que se vea diferente al de las capturas de pantalla que se muestran aquí.

Crea un proyecto nuevo

Crea un proyecto nuevo con la plantilla Universal Render Pipeline. Asígnale un nombre descriptivo y una ubicación adecuada, y presiona CREAR.

Instala los frameworks necesarios

Puedes encontrar la base de RA de Unity en Unity Package Manager.

  1. Ábrelo haciendo clic en Ventana > Administrador de paquetes

  1. En esta ventana, instala los paquetes que usarás en este codelab. Para ver las versiones más recientes de estos frameworks, expande su entrada con el ícono . Instala las versiones más recientes de cada uno de estos marcos de trabajo:
    • AR Foundation
    • Complemento de ARCore XR

Cuando finalices, el Administrador de paquetes debería verse así:

Instala el paquete inicial

En este codelab, proporcionamos un paquete inicial que contiene prefabs y secuencias de comandos que acelerarán algunas partes del codelab, de modo que puedas enfocarte en usar AR Foundation.

  1. Instala el paquete de inicio abriendo Recursos > Importar paquete > Custom Package... y abre starter-package.unitypackage.
  2. En la ventana emergente, asegúrate de que esté todo seleccionado.
  3. Haz clic en Importar.

Cómo cambiar la configuración de compilación

Dado que la aplicación se ejecutará en Android, cambia la plataforma de compilación a Android:

  1. Abre Archivo > Build Settings
  2. En el panel Platform, selecciona Android.
  3. De manera opcional, habilita la Compilación de desarrollo y Depuración de secuencias de comandos para conservar la información de depuración mientras se ejecuta tu app.
  4. Haz clic en Switch Platform.

Cambiar la configuración del proyecto

AR Foundation debe configurarse para inicializar los sistemas XR en el inicio.

  1. Abre Editar > Project Settings... y haz clic en la sección XR Plug-in Management.
  2. En la pestaña Android, habilita ARCore.

  1. En el panel de la izquierda, haz clic en la sección Reproductor.
  2. En la pestaña Android, en Other Settings, quita Vulkan de Graphics APIs.

  1. Las apps de RA que usen ARCore requieren un nivel de API 24 como mínimo. Desplázate hacia abajo y busca Minimum API Level. Establece el nivel de API mínimo en 24.

Agrega los elementos de escena requeridos

La plantilla de la canalización universal de renderizaciones incluye algunos objetos de juego que no usarás en este instructivo.

  1. Borra todos los objetos del juego en SampleScene.

  1. Agrega objetos de AR Foundation. Haz clic con el botón derecho en el panel Hierarchy. Usa este menú para agregar lo siguiente:
  • XR > Sesión de RA: Este objeto controla el ciclo de vida de una experiencia de RA.
  • XR > Origen de la sesión de RA: Este objeto transforma las coordenadas de RA en coordenadas mundiales de Unity.
  • Claro > Luz direccional: Proporciona una fuente de luz para iluminar los objetos del juego.

Tu jerarquía debería verse así:

  1. Expande el Origen de la sesión de RA que creaste en la jerarquía y selecciona el objeto Cámara de RA. En el inspector, cambia su etiqueta a MainCamera.

Configura el procesamiento

La canalización universal de renderizaciones de Unity necesita un cambio para ser compatible con AR Foundation.

  1. En el panel Project, navega por Assets > Settings para encontrar el recurso ForwardRenderer.

  1. Selecciona ForwardRenderer.
  2. En el panel Inspector, usa la opción Add Renderer Feature para agregar una función del renderizador en segundo plano de RA. Este componente renderizará el feed de la cámara en la escena.

Verifique la configuración

  1. Asegúrate de que tu dispositivo esté conectado y que la depuración ADB esté activada.
  2. Haz clic en Archivo > Compila y ejecuta... Esta acción subirá la aplicación a tu dispositivo y la iniciará cuando esté instalada.
  3. Deberías ver el feed de la cámara en la pantalla del dispositivo.

En el siguiente paso, comenzarás a agregar funcionalidad a tu app.

3. Detecta aviones en el mundo real

Ahora que ya configuraste una escena básica, puedes comenzar a desarrollar el juego. En este paso, detectarás planos y los dibujarás en la escena.

Cómo agregar un componente ARPlaneManager

Un ARPlaneManager detecta ARPlane y crea, actualiza y quita objetos de juego cuando cambia la comprensión del entorno del dispositivo.

  1. En el panel Hierarchy, crea un GameObject vacío.
  2. Cámbiale el nombre a Driving Surface Manager. En este componente, se mostrarán planos hasta que el jugador seleccione uno.
  3. Selecciona el nuevo objeto de juego. En el panel Inspector, haz clic en Add Component para agregar un AR Plane Manager.

  1. Para configurar ARPlaneManager, establece el campo Plane Prefab:
    1. Haz clic en el botón junto a None para abrir la ventana Select GameObject (Seleccionar GameObject).
    2. Selecciona la pestaña Assets y busca Driving Surface Plane.

Este prefab del paquete de inicio proporciona una textura de piso arenosa que se usará como decoración del plano.

  1. Cambia Detection Mode a Horizontal. De esta manera, se configura el ARPlaneManager para que solo proporcione planos horizontales, lo que es ideal para conducir.

Cómo agregar un componente ARRaycastManager

Un elemento ARRaycastManager expone la funcionalidad de raycast. En el siguiente paso, usaremos este objeto para proporcionar los controles para el usuario.

  1. Asegúrate de que el objeto llamado Driving Surface Manager esté seleccionado en el panel Hierarchy.
  2. En el Inspector, haz clic en Add Component para agregar un componente ARRaycastManager a tu objeto de juego.

No se necesita configuración adicional para este componente.

Cómo agregar un componente DrivingSurfaceManager

Un DrivingSurfaceManager es una secuencia de comandos auxiliar del paquete inicial que permite seleccionar un ARPlane. Una vez que se seleccione un ARPlane, se ocultarán todos los demás planos y se inhabilitarán los nuevos.

  1. Asegúrate de que el objeto llamado Driving Surface Manager esté seleccionado en el panel Hierarchy.
  2. En el Inspector, haz clic en Add Component para agregar un componente DrivingSurfaceManager a tu objeto de juego.

No se necesita configuración adicional para este componente.

Ejecuta la app

  1. Haz clic en Archivo > Build And Run... para probar los cambios.
  2. Apunta tu dispositivo a una superficie horizontal real y muévelo para mejorar la comprensión de ARCore del mundo.

  1. Cuando ARCore detecte un plano, deberías ver una textura de suciedad que cubre superficies del mundo real. El ARPlaneManager crea una instancia del Plane Prefab proporcionado para cada plano detectado. El prefab Driving Surface Plane tiene un componente ARPlaneMeshVisualizer que crea una malla para un ARPlane determinado.

En el siguiente paso, usarás un plano detectado como campo de juego.

4. Realiza una prueba de posicionamiento en los planos detectados

En el paso anterior, programaste una aplicación que puede detectar planos. Estos aviones se reflejarán en la escena de tu juego. Ahora, agregarás interactividad con estos aviones creando un retículo de apuntar y un automóvil que conducirá en la superficie del avión detectado.

Crea un retículo de apuntar

El esquema de control de esta app implica que el jugador apunte su teléfono a una superficie. Para brindar comentarios visuales claros para la ubicación designada, usarás un retículo de apuntar.

Para «mantener» este retículo a un plano de RA, usa una prueba de posicionamiento. Una prueba de posicionamiento es una técnica que calcula las intersecciones cuando se proyecta un rayo en una dirección determinada. Usarás una prueba de posicionamiento para detectar una intersección en la dirección de la vista de la cámara.

Agrega el retículo

  1. En el panel Project que se encuentra cerca de la parte inferior de la pantalla, navega a Assets > Paquete básico
  2. Coloca el Prefab Reticle en la escena arrastrándolo al panel de jerarquía del proyecto.
  3. Selecciona el retículo en la jerarquía.
  4. En el inspector, haz clic en Add Component. Agrega la secuencia de comandos ReticleBehaviour del paquete inicial. Esta secuencia de comandos contiene código estándar para controlar el retículo.
  5. La secuencia de comandos ReticleBehaviour depende del Driving Surface Manager que creaste antes, así que haz clic en el selector Driving Surface Manager para agregar la dependencia. Selecciona la pestaña Scene y elige la Driving Surface Manager.

Edita el ReticleBehaviour

La secuencia de comandos ReticleBehavior posicionará el retículo en el plano que está en el centro del viewport del dispositivo.

  1. Haz doble clic en el campo Script para abrir la secuencia de comandos ReticleBehaviour.cs.
  2. Determina el centro de la pantalla con el ViewToScreenPoint de la cámara. Edita el método Update() para agregar lo siguiente:
var screenCenter = Camera.main.ViewportToScreenPoint(new Vector3(0.5f, 0.5f));
  1. Usa este punto para realizar una proyección de rayos. Agrega las siguientes:
var hits = new List<ARRaycastHit>();
DrivingSurfaceManager.RaycastManager.Raycast(screenCenter, hits, TrackableType.PlaneWithinBounds);

La variable hits contendrá ARRaycastHit que describen puntos de los elementos rastreables que se cruzan con ray.

  1. Consulta la lista hits para determinar la intersección de lugares de interés. Prioriza el plano bloqueado contenido en DrivingSurfaceManager y, si no existe, usa el primer hit de plano. Agrega lo siguiente al final de Update():
CurrentPlane = null;
ARRaycastHit? hit = null;
if (hits.Length > 0)
{
    // If you don't have a locked plane already...
    var lockedPlane = DrivingSurfaceManager.LockedPlane;
    hit = lockedPlane == null
        // ... use the first hit in `hits`.
        ? hits[0]
        // Otherwise use the locked plane, if it's there.
        : hits.SingleOrDefault(x => x.trackableId == lockedPlane.trackableId);
}
  1. Si hit contiene un resultado, mueve la transformación de esta GameObject a la posición de hit.
if (hit.HasValue)
{
    CurrentPlane = DrivingSurfaceManager.PlaneManager.GetPlane(hit.Value.trackableId);
    // Move this reticle to the location of the hit.
    transform.position = hit.Value.pose.position;
}
Child.SetActive(CurrentPlane != null);

Prueba el retículo

  1. Haz clic en Archivo > Build And Run... para probar los cambios.
  2. Cuando apuntes tu dispositivo a un avión, deberías ver que el retículo sigue los movimientos de la cámara.

Crear un auto

El jugador controlará un auto de juguete que conducirá hacia la ubicación del retículo. En el paquete básico, se incluyen el modelo y el comportamiento de este vehículo.

Agrega un CarManager a tu escena

  1. En Hierarchy, crea un nuevo GameObject vacío.
  2. Cámbiale el nombre a Car Spawner.
  3. Selecciona el objeto que creaste. En el panel Hierarchy, haz clic en Add Component para agregar el componente CarManager.
  4. Haz clic en el selector de cada campo para configurar las dependencias de CarManager:
    • Car Prefab: En Assets, selecciona Car Prefab.
    • Reticle: En Scene, selecciona Reticle Prefab.
    • Driving Surface Manager: En Scene, selecciona Driving Surface Manager.

Este comportamiento CarManager genera un auto de juguete en el avión en el que se encuentra el retículo. Si quieres, consulta la secuencia de comandos de CarBehaviour para ver cómo se programa el auto.

Prueba de conducción

  1. Haz clic en Archivo > Build And Run para probar los cambios
  2. Cuando presiones un avión, deberías ver un auto pequeño en esa ubicación. Este auto seguirá el retículo.

Agrega el elemento del juego

Ahora que el jugador puede controlar una entidad de la escena, ofrécele un destino hacia el cual dirigirse.

  1. Crea un nuevo GameObject vacío en la jerarquía.
  2. Cámbiale el nombre a Package Spawner.
  3. Selecciona el objeto que creaste. En el panel Hierarchy, haz clic en Add Component para agregarle el componente PackageSpawner.
  4. Haz clic en el selector de cada campo para configurar las dependencias de PackageSpawner:
    • Package Prefab: En Assets, selecciona Package Prefab.
    • Driving Surface Manager En Scene, selecciona Driving Surface Manager.

Este comportamiento PackageSpawner genera un paquete nuevo en una ubicación aleatoria en un ARPlane bloqueado si aún no hay un paquete.

Prueba el juego

  1. Haz clic en Archivo > Build And Run para probar los cambios 2. Después de crear un auto, se debería generar un paquete.
  2. Conduce el automóvil hasta el paquete.
  3. Aparecerá uno nuevo en una ubicación aleatoria.

5. Configura la estimación de la iluminación

Ahora que completaste el juego básico, agrega un toque de realismo a tu escena de RA. En este paso, usarás la API de Lighting Estimation de ARCore para detectar la iluminación presente en el mundo real en función de los fotogramas de cámara entrantes. Esta información se utilizará para adaptar la iluminación de la escena de modo que coincida con la iluminación del mundo real.

Habilitar estimación de iluminación

  1. En Hierarchy, expande AR Session Origin y selecciona el objeto AR Camera (Cámara de RA).
  2. En el Inspector, expande la secuencia de comandos del AR Camera Manager.
  3. Cambia el campo Estimación de la iluminación a Todo.

Modificar la luz direccional

  1. En Hierarchy, selecciona el objeto Addressal Light.
  2. Agrégale el componente LightEstimation. Este componente del paquete inicial proporciona código estándar para suscribirse a los cambios de iluminación.
  3. En la función FrameReceived(), agrega lo siguiente:
ARLightEstimationData lightEstimation = args.lightEstimation;

if (lightEstimation.averageBrightness.HasValue)
    Light.intensity = lightEstimation.averageBrightness.Value;

if (lightEstimation.averageColorTemperature.HasValue)
    Light.colorTemperature = lightEstimation.averageColorTemperature.Value;

if (lightEstimation.colorCorrection.HasValue)
    Light.color = lightEstimation.colorCorrection.Value;

if (lightEstimation.mainLightDirection.HasValue)
    Light.transform.rotation = Quaternion.LookRotation(lightEstimation.mainLightDirection.Value);

if (lightEstimation.mainLightColor.HasValue)
    Light.color = lightEstimation.mainLightColor.Value;

if (lightEstimation.mainLightIntensityLumens.HasValue)
    Light.intensity = lightEstimation.averageMainLightBrightness.Value;

if (lightEstimation.ambientSphericalHarmonics.HasValue)
{
    RenderSettings.ambientMode = AmbientMode.Skybox;
    RenderSettings.ambientProbe = lightEstimation.ambientSphericalHarmonics.Value;
}

Prueba tus cambios

  1. Haz clic en Archivo > Build And Run para probar los cambios
  2. Al mirar los objetos en la escena, es posible que notes que están de color según la iluminación del entorno.
  3. Si es posible, intenta modificar la iluminación. Por ejemplo, intenta apagar las luces de la habitación en la que te encuentras. Deberías ver que la iluminación de los objetos se adapta al cambio de la iluminación del mundo real.

6. Conclusión

¡Felicitaciones! Llegaste al final de este codelab sobre Unity AR Foundation.

Temas abordados

  • Cómo configurar un proyecto básico con AR Foundation de Unity y la canalización universal de renderizaciones
  • Cómo usar ARPlaneManager para suscribirse a aviones nuevos
  • Cómo usar Raycast para encontrar intersecciones con geometría virtual
  • Cómo usar ARLightEstimationData para iluminar la escena

Próximos pasos

Tareas bonificadas

Si quieres expandir el juego que creaste aquí, aquí hay algunas ideas que puedes aplicar:

  • Para agregar un contador de puntuaciones al juego, modifica un elemento TextMeshPro cuando un objeto PackageManager genere un paquete nuevo.
  • Para consultar la información de rendimiento cuando el juego se esté ejecutando, habilita la Superposición de rendimiento.
  • Usa Raycasts persistentes para colocar objetos nuevos en la escena primero. Cuando se detecte un plano en esa área, ese objeto se actualizará para ajustarse a ese plano.