Oneof los desafíos de la realidad virtual es la locomoción. En la sala de escala VR usuarios pueden caminar, pero el espacio limitado es un problema. Los usuarios móviles de realidad virtual con sólo tres grados de libertad tienen que depender de movimiento de la cabeza o de los controladores.

El teletransporte es una forma divertida de moverse por las limitaciones de la realidad virtual. Aunque no es verdaderamente natural, los usuarios están acostumbrados al concepto de teletransporte de ciencia ficción y fantasía, y no es difícil de implementar.

Vamos a construir una escena para Oculus Go / VR engranaje que demuestra teletransporte usar el controlador como un puntero.

Tabla de contenidos

Código fuente

El proyecto de la Unidad para este tutorial está disponible para su descarga aquí. Para ahorrar espacio, Oculus Utilities y VR escenas de muestra no están incluidos, pero los archivos de origen que fueron modificados se incluyen en el nivel superior del proyecto. Estos archivos son OVRPlugin.cs, VREyeRaycaster.cs y Reticle.cs.

No se pierda! extremos de la oferta en

  • Accede a los más de 200 cursos
  • Nuevos cursos añadió mensual
  • Cancelar en cualquier momento
  • Los certificados de terminación

    ACCESO ahora

    Configuración

    Para comenzar, cree un nuevo proyecto de la Unidad, teletransportador. Cree la carpeta Activos / plugins / Android / activos dentro del proyecto, y copiar archivo de firma Oculus del teléfono allí. Ver https://dashboard.oculus.com/tools/osig-generator/ para crear un nuevo archivo de firma.

    Seleccione Archivo -> configuración de generación en el menú y elegir Android como plataforma. Haga clic en Configuración del reproductor para cargar PlayerSettings en inspector de la Unidad. Añadir Oculus bajo Realidad Virtual SDK y seleccione API nivel 19 como el API de nivel mínimo.

    Descargar Oculus Utilidades de https://developer.oculus.com/downloads/package/oculus-utilities-for-unity-5/ y extraer el archivo zip en su ordenador. Utilidades de importación Oculus en su proyecto mediante la selección de Activos -> Importar paquete -> paquete personalizado dentro de la Unidad y la elección de la ubicación del paquete que ha extraído. Si se le solicita que actualice el paquete, siga las instrucciones para instalar la actualización y reiniciar la unidad.

    Una carpeta con el nombre de Oculus se creará en su proyecto. Óculo / Prefabs contiene las casas prefabricadas OVRCameraRig y TrackedRemote que vamos a utilizar para implementar soporte para el controlador. Si expande TrackedRemote en la vista del proyecto, verá que contiene prefabricadas para los controladores de engranaje de VR y Oculus Go.


    Si recibe el mensaje de error “ ‘OVRP_1_15_0’ no existe en el contexto actual,” Activos de apertura / Oculus / VR / scripts / OVRPlugin.cs y añadir #if! OVRPLUGIN_UNSUPPORTED_PLATFORM y #endif alrededor de código que comprueba la versión OVRPlugin . Puede encontrar una copia fija de OVRPlugin.cs en la fuente incluido. Este error probablemente no se produce en Windows.

    También necesitará el paquete de muestras VR de la tienda de Activos Unidad. Este paquete incluye una serie de escenas de muestra, así como casas prefabricadas y scripts que vamos a personalizar para añadir un puntero láser y el retículo. Haga clic en la ficha Activos tienda en la unidad, y la búsqueda de “muestras de realidad virtual.” Cuando se carga, haga clic en el botón Importar y siga las instrucciones para importar este paquete. Las carpetas y VRSampleScenes VRStandardAssets se crearán en la carpeta Activos.

    Preparación del auricular

    Si está utilizando el engranaje VR, tendrá que activar el modo desarrollador en su teléfono para probar la aplicación. En la configuración del teléfono, vaya a “Acerca del dispositivo” y pulse siete veces en “Número de compilación.”

    También tendrá que activar el modo desarrollador si está utilizando un óculo Go. En primer lugar, es necesario crear una organización en su cuenta de Oculus en https://dashboard.oculus.com/. Luego, en la aplicación móvil de Oculus, elegir el auricular que está utilizando en el menú Configuración, seleccione Más configuraciones, y alternar el modo de desarrollador. Ver https://developer.oculus.com/documentation/mobilesdk/latest/concepts/mobile-device-setup-go/ para más detalles.

    cámara y el controlador

    Empecemos mediante la creación de una cámara VR y la adición de soporte para el controlador. En primer lugar, retire el objeto principal de la cámara que se crea de forma predeterminada. Vamos a utilizar una cámara personalizada.

    Crea una instancia de la OVRCameraRig prefabricadas incluido en Oculus Utilidades arrastrando Activos / Oculus / VR / Prefabs / OVRCameraRig desde la ventana del proyecto a la ventana de jerarquía. Ampliar OVRCameraRig, y verá que contiene una TrackingSpace con anclajes para los ojos y las manos. Ajustar la posición ofOVRCameraRig a (0, 1,8, 0) para aproximar la altura de una persona.


    CenterEyeAnchor es el marcador de posición para nuestra cámara que vamos a sustituir con el MainCamera prefabricadas incluido en las escenas de muestra VR. Activos de arrastre / VRSampleScenes / Prefabs / Utilidades / MainCamera desde la ventana del proyecto a la jerarquía. Cambiar el nombre de esta instancia CenterEyeAnchor y anidan en los términos de OVRCameraRig -> TrackingSpace. Retire la CenterEyeAnchor originales.

    Ahora agregue el controlador usando los Activos / Oculus / Prefabs / TrackedRemote prefabricadas. Crear instancias de TrackedRemote como hijos de OVRCameraRig-> TrackingSpace -> LeftHandAnchor y OVRCameraRig -> TrackingSpace -> RightHandAnchor. TrackedRemote contiene modelos tanto para el controlador de engranaje VR y el controlador de Oculus Go. Cuando se ejecuta esta escena, se muestra el modelo de controlador correcto en función del kit manos libres portátil que está utilizando.


    Asegúrese de que el controlador de campo de la instancia TrackedRemote bajo LeftHandAnchor se establece en “L orugas remoto”. La instancia bajo RightHandAnchor se debe establecer en “R orugas remoto”. Usted puede hacer esto en el inspector de la Unidad.

    Si ambas manos están configurados correctamente, el controlador se mostrará automáticamente para la mano correcta cuando se ejecuta la escena.

    A continuación, añadir un rayo láser que se extiende desde el controlador. Añadir un procesador de línea de CenterEyeAnchor haciendo clic en “Agregar componente” en el inspector y escribiendo “Línea Procesador” en el buscador. Desactivar “Recibir sombras” y fijar el material a MazeAgentPath, un material de color rojo que se incluye con el paquete de escenas de muestra VR. Si quieres un láser de diferentes colores, se puede crear fácilmente un material de diferente color y utilizarlo en la línea Renderizador.

    Bajo el campo Ancho, arrastre el control deslizante hacia abajo para ajustar una anchura de aproximadamente (0,0, 0,02). Si la anchura es demasiado grueso, el rayo láser se verá como un gran bloque en lugar de un rayo.


    Codificación de un rayo láser

    Nuestro próximo paso será convertir el controlador en un puntero láser. Para ello, modificamos los scripts adjuntos a CenterEyeAnchor y VRCameraUI siguiendo los pasos descritos en https://developer.oculus.com/blog/adding-gear-vr-controller-support-to-the-unity-vr-samples/ . Las secuencias de comandos modificadas están incluidas en el paquete de código fuente que viene con este tutorial.

    Los activos script / VRStandardAssets / Scripts / VREyeRaycaster.cs se une a CenterEyeAnchor. Añadir estos campos a la clase VREyeRaycaster:
    [SerializeField] privado LineRenderer m_LineRenderer = null; ShowLineRenderer public bool = true; 12 [SerializeField] privateLineRenderer m_LineRenderer = null; publicboolShowLineRenderer = true;

    Añadir los siguientes descriptores de acceso a VREyeRaycaster:
    / * Los descriptores de acceso para el controlador * / public bool ControllerIsConnected {get {OVRInput.Controller controlador = OVRInput.GetConnectedControllers () y (OVRInput.Controller.LTrackedRemote | OVRInput.Controller.RTrackedRemote); volver controlador == OVRInput.Controller.LTrackedRemote || controlador == OVRInput.Controller.RTrackedRemote; }} Controller OVRInput.Controller público {get {OVRInput.Controller controlador = OVRInput.GetConnectedControllers (); if ((controlador y OVRInput.Controller.LTrackedRemote) == OVRInput.Controller.LTrackedRemote) {return OVRInput.Controller.LTrackedRemote; } Else if ((controlador y OVRInput.Controller.RTrackedRemote) == OVRInput.Controller.RTrackedRemote) {return OVRInput.Controller.RTrackedRemote; } Devolver OVRInput.GetActiveController (); }} 1234567891011121314151617181920 / * Los descriptores de acceso para el controlador * / publicboolControllerIsConnected {get {OVRInput.Controller controlador = OVRInput.GetConnectedControllers () y (OVRInput.Controller.LTrackedRemote | OVRInput.Controller.RTrackedRemote); returncontroller == || OVRInput.Controller.LTrackedRemote controlador == OVRInput.Controller.RTrackedRemote;}} publicOVRInput.Controller Controller {get {OVRInput.Controller controlador = OVRInput.GetConnectedControllers (); if ((controlador y OVRInput.Controller.LTrackedRemote) == OVRInput.Controller.LTrackedRemote) {return OVRInput. Controller.LTrackedRemote;} elseif ((controlador y OVRInput.Controller.RTrackedRemote) == OVRInput.Controller.RTrackedRemote) {return OVRInput.Controller.RTrackedRemote;} returnOVRInput.GetActiveController ();}}

    controlador determina que está conectado controlador, y ControllerIsConnected determina si está conectado un controlador.

    Ahora busca la función EyeRaycast y encontrar la línea:
    RaycastHit golpeado;

    Después de esta línea, añadir:
    Vector3 worldStartPoint = Vector3.zero; vector3 worldEndPoint = Vector3.zero; si (m_LineRenderer! = Null) {m_LineRenderer.enabled = ControllerIsConnected && ShowLineRenderer;} 12345Vector3 worldStartPoint = Vector3.zero; vector3 worldEndPoint = Vector3.zero; if (! = M_LineRenderer null) {m_LineRenderer.enabled = ControllerIsConnected && ShowLineRenderer;}.

    Este código permite que el procesador de línea, haciendo que el haz de láser visible, sólo si un controlador está conectado

    Añadir más después de este código para convertir la posición y rotación local del controlador de coordenadas mundiales:
    Si {Matrix4x4 localToWorld = m_TrackingSpace.localToWorldMatrix (ControllerIsConnected && m_TrackingSpace! = null); orientación Quaternion = OVRInput.GetLocalControllerRotation (Controller); Vector3 localStartPoint = OVRInput.GetLocalControllerPosition (Controller); Vector3 LocalEndPoint = localStartPoint + ((orientación * Vector3.forward) * 500.0f); worldStartPoint = localToWorld.MultiplyPoint (localStartPoint); worldEndPoint = localToWorld.MultiplyPoint (LocalEndPoint); // Crear nuevo rayo rayos = new Ray (worldStartPoint, worldEndPoint – worldStartPoint);} 12345678910111213if (ControllerIsConnected && m_TrackingSpace! = Null) {Matrix4x4 localToWorld = m_TrackingSpace.localToWorldMatrix; cuaternión de orientación = OVRInput.GetLocalControllerRotation (controlador); Vector3 localStartPoint = OVRInput.GetLocalControllerPosition (Controller); Vector3 LocalEndPoint = localStartPoint + ((orientación * Vector3.forward) * 500.0f); worldStartPoint = localToWorld.MultiplyPoint (localStartPoint); worldEndPoint = localToWorld.MultiplyPoint (LocalEndPoint); // Crear nueva rayray = NewRay (worldStartPoint, worldEndPoint -worldStartPoint);}

    Ahora busca la línea:
    VRInteractiveItem interactible = hit.collider.GetComponent (); 1VRInteractiveItem interactible = hit.collider.GetComponent ();

    y añadir el siguiente código después de que:
    si (interactible) {worldEndPoint = hit.point;} 123if (interactible) {worldEndPoint = hit.point;}.

    Esto establece el punto final del haz de láser a la posición de cualquier VRInteractiveItem que golpea

    Al final de la función EyeRaycast, añadir:
    if (! ControllerIsConnected && m_LineRenderer = null) {m_LineRenderer.SetPosition (0, worldStartPoint); m_LineRenderer.SetPosition (1, worldEndPoint);} 1234if (ControllerIsConnected && m_LineRenderer = null) {m_LineRenderer.SetPosition (0, worldStartPoint); m_LineRenderer.SetPosition (1, worldEndPoint);}

    para hacer los puntos extremos del haz de láser la mismo que los puntos finales del rayo que estamos fundición.

    retículo

    El extremo del haz de láser tendrá una retícula, o un círculo de orientación. El MainCamera prefabricada ya incluye una retícula que se muestra en frente de la cámara. Vamos a cambiar su código para que la retícula se visualiza automáticamente al final del rayo láser si un controlador está conectado, pero aparece delante de la cámara si no hay un controlador.

    en activos / VRSampleScenes / Scripts / / Reticle.cs, encontrar el SetPosition) Utilidades de la función (. Cambiar esta función para que toma dos argumentos, una posición y una dirección:
    SetPosition pública vacío (posición Vector3, Vector3 adelante) {// Establecer la posición del punto de mira a la distancia predeterminada en frente de la cámara. m_ReticleTransform.position = posición + adelante * m_DefaultDistance; // Establecer la escala basado en el original y la distancia de la cámara. m_ReticleTransform.localScale = m_OriginalScale * m_DefaultDistance; // La rotación debe ser sólo el valor predeterminado. m_ReticleTransform.localRotation = m_OriginalRotation;} 12345678910publicvoidSetPosition (posición Vector3, Vector3 adelante) {// Set la posición de la retícula a la distancia predeterminada delante de la camera.m_ReticleTransform.position = posición + adelante * m_DefaultDistance; // Establecer la escala basada en el original y la distancia desde la camera.m_ReticleTransform.localScale = m_OriginalScale * m_DefaultDistance; // la rotación debe ser sólo el default.m_ReticleTransform.localRotation = m_OriginalRotation;}

    veremos un error de compilación sobre SetPosition () hasta añadimos los argumentos ray.origin y ray.direction a m_Reticle.SetPosition al final de la función VREyeRayCaster.EyeRaycast:
    si (m_Reticle) m_Reticle.SetPosition (ray.origin, ray.direction); 12Si (m_Reticle) m_Reticle.SetPosition (ray.origin, ray.direction);

    Para todo tirón juntas en la unidad, asegúrese de que los campos de VREyeRayCaster en el inspector están llenos. Usted tendrá que añadir manualmente a CenterEyeAnchor el campo “Línea Procesador”, que rellena m_LineRenderer y TrackingSpace al campo “Seguimiento Espacial”.


    Si ejecuta la escena en un auricular, la retícula aparecerá al final del rayo láser que se extiende desde el controlador.


    Teleport Manager y reproductor

    Ha llegado el momento de poner en práctica los guiones de teletransporte. Crear una GameObject vacío denominado TeleportManager. Crear un nuevo guión, Activos / scripts / TeleportManager.cs, y adjuntarlo a la TeleportManager GameObject.

    Abrir TeleportManager.cs y crear la clase:
    using System; usando UnityEngine; utilizando VRStandardAssets.Utils; public class TeleportManager: MonoBehaviour {public static evento Acción DoTeleport; [SerializeField] VRInteractiveItem [] teleportLocations; [SerializeField] Transformar reticleTransform;} 123456789using System; usando UnityEngine; usando VRStandardAssets.Utils; publicclassTeleportManager: MonoBehaviour {publicstaticevent Acción DoTeleport; [SerializeField] VRInteractiveItem [] teleportLocations; [SerializeField] Transform reticleTransform;}

    El componente VRInteractiveItem , que se define en el activo / VRStandardAssets / Scripts / VRInteractiveItem.cs, le permite interactuar con objetos en VR. VRInteractiveItem proporciona eventos que se activan cuando se producen diferentes tipos de interacciones. Vamos a utilizar el evento OnClick.

    teleportLocations es una matriz de VRInteractiveItems que, cuando se hace clic, hacer que el usuario de teletransporte a la ubicación de la retícula. Vamos a llenar teleportLocations del inspector.

    Cuando la retícula se dirige a una ubicación de teletransporte, y se hace clic en el controlador, el jugador será transportado a la posición de reticleTransform.

    El teletransporte real se llevará a cabo por el objeto Player, que vamos a crear más adelante. Playerwill contener un método que se suscribe a TeleportManager.DoTeleport. DoTeleport es un evento como VRInteractiveItem.OnClick.

    Dentro TeleportManager, añadir los métodos siguientes:
    void OnEnable () {foreach (VRInteractiveItem t en teleportLocations) {t.OnClick + = Teleport; }} Void OnDisable () {foreach (VRInteractiveItem t en teleportLocations) {t.OnClick – = Teleport; }} Void Teleport () {if (DoTeleport! = Null) {DoTeleport (reticleTransform); } Else {debug.log ( «evento DoTeleport no tiene suscriptores.»); }} 12345678910111213141516171819voidOnEnable () {foreach () {VRInteractiveItemtinteleportLocations t.OnClick + = Teleport;}} voidOnDisable () {foreach () {VRInteractiveItemtinteleportLocations t.OnClick- = Teleport;}} voidTeleport () {if (! DoTeleport = null) {DoTeleport (reticleTransform);} else {debug.log ( «evento DoTeleport no tiene suscriptores.»);}}

    OnEnable es llamado automáticamente cuando se crea el TeleportManager. En OnEnable, el método Teleport suscribe al evento OnClick de cada lugar de teletransporte. TeleportManager.Teleportis ejecutarse cada vez que se hace clic en una ubicación de teletransporte. OnDisable cancele la suscripción Teleport cuando el objeto TeleportManager se destruye. pérdidas de memoria impide darse de baja.

    El método Teleport llama a la acción DoTeleport, lo que provoca que se suscriben a métodos de ejecución.

    Ahora vamos a crear un objeto contenedor para el jugador. Crear una GameObject vacío con el nombre del jugador, y adjuntar un nuevo guión, Activos / Scripts / Player.cs. Nido OVRCameraRig bajo jugador ya que la cámara es el punto de vista del jugador. La posición de Conjunto del jugador a (0, 1,8, 0), y restablecer la posición de OVRCameraRig a (0, 0, 0). La posición de OVRCameraRig está ahora en relación con jugador.


    Agregue el código para Player.cs:
    using System; usando System.Collections; usando System.Collections.Generic; usando UnityEngine; public class jugador: MonoBehaviour {Vector3 playerPosition; // seguimiento de dónde serán transportados jugador. [SerializeField] flotar playerHeight = 1.8F; OnEnable void () {TeleportManager.DoTeleport + = MoveTo; OnDisable} void () {TeleportManager.DoTeleport – = MoveTo; } MoveTo vacío (Transform destTransform) {// Establecer la nueva posición. playerPosition = destTransform.position; // altura de los ojos del jugador debe ser playerHeight por encima de la nueva posición. playerPosition.y + = playerHeight; // Mover jugador. transform.position = playerPosition; }} 12345678910111213141516171819202122232425262728using System; usando System.Collections; usando System.Collections.Generic; usando UnityEngine; publicclassPlayer:. MonoBehaviour {Vector3 playerPosition; // seguimiento de dónde serán transportados jugador [SerializeField] floatplayerHeight = 1.8F; voidOnEnable () { TeleportManager.DoTeleport + = MoveTo;} voidOnDisable () {TeleportManager.DoTeleport- = MoveTo;} voidMoveTo (Transform destTransform) {// Establecer la nueva position.playerPosition = destTransform.position; // altura de los ojos del jugador debe ser playerHeight por encima de la nueva posición .playerPosition.y + = playerHeight; // Mover Player.transform.position = playerPosition;}}

    playerPosition es un marcador de posición para la posición donde serán transportados al jugador. playerHeight existe porque tenemos que tener altura de los ojos del jugador en consideración cuando teletransportarse.

    En OnEnable, el método Player.MoveTo está suscrito al evento TeleportManager.DoTeleport. La anulación de la suscripción se produce en OnDisable.

    Player.MoveTodoes el trabajo de teletransportarse a un jugador. Añadimos playerHeight a la coordenada y del destino de transformación de posición para tener en cuenta el nivel del ojo. Entonces nos movemos jugador mediante la actualización de la posición de su transformación al nuevo destino.

    Creación de Teleport Ubicaciones

    Nuestro último paso será la creación de lugares de teletransporte.

    En la jerarquía de la Unidad, crear un avión llamado “tierra” y colocarlo en el origen. Ampliación de tierra y adjuntar VRStandardAssets / Scripts / VRInteractiveItem.cs. Crear un par de cubos situados en el suelo para servir como puntos de referencia. A medida que telepuerto en el suelo, estos puntos de paso nos ayudará a comprender dónde estamos.

    Ahora cree unos cubitos finos y formarlos en los escalones de una escalera. Nido de las escaleras en un GameObject vacío denominado escaleras, y se adhieren a VRInteractiveItem.cs cada escalón.


    Por último, para tirar todo junto, vamos a rellenar los campos de TeleportManager. En el inspector, abra el campo “Teleport ubicaciones”, y establecer el tamaño igual al número de VRInteractiveItems. Rellena los elementos de arrastre de tierra y cada una de las escaleras de la ventana de jerarquía de los campos en el inspector. Rellene el “retículo Transform” campo con GUIReticle.

    Construcción del Proyecto

    Ahora estamos listos para probar la aplicación. Enchufe los auriculares Oculus Go o su teléfono de Samsung, y seleccionar “Construir y Ejecutar” en el menú Archivo. Si todo funciona, usted será capaz de teletransportarse a cualquier lugar en el suelo o en las escaleras apuntando el mando y haciendo clic en el botón de disparo. Ahora ha aplicado con éxito en teletransporte VR!
    > <img src = < p> Crédito: imagen destacado de la foto de Martín Sánchez en Unsplash

    Mensajes relacionados
    > <img src =

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *