Crea un juego de realidad aumentada estilo Pokémon GO con Vuforia Parte 2

Lo que vas a crear

En la última publicación de esta serie, aprendimos cómo configurar Vuforia y comenzar a desarrollar un juego AR desde cero, adoptando una lógica similar a la utilizada en Pokémon GO!

  • Crea un juego de realidad aumentada estilo Pokémon GO con Vuforia

    En este tutorial, comenzaremos a crear una aplicación con Realidad Aumentada utilizando Vuforia en Unity 3D. Aprenderemos cómo configurar Vuforia y comenzar a desarrollar un AR ...
    Estaño megali
    Desarrollo móvil
  • Pokémon GO Style Realidad Aumentada Con Vuforia

    Con el éxito viral de Pokemon GO, todo el mundo ha estado hablando de la realidad aumentada. En este tutorial veremos cómo usar Vuforia para la realidad aumentada ...
    Estaño megali
    Desarrollo móvil
  • Pokémon GO Style Realidad Aumentada: Marcadores

    Recientemente, Pokémon Go ha tomado al mundo por asalto. Una de las partes más interesantes y atractivas de este juego es el uso de realidad aumentada, o AR. AR es ...
    Derek Jensen
    Aplicación movil

Hemos iniciado el desarrollo de un juego de Realidad Aumentada llamado Shoot the Cubes. Ahora es el momento de mejorar el juego agregando interacción y haciendo que la experiencia sea más atractiva. Nos concentraremos principalmente en las posibilidades que nos brinda Unity, dejando de lado los detalles de Vuforia. La experiencia con el motor de Unity no es obligatoria..

1. Haciendo que los cubos se vean vivos

Vamos a empezar a trabajar en nuestro juego. Hasta ahora hemos logrado crear una escena de Realidad Aumentada que se mueve con el dispositivo del usuario. Mejoraremos esta aplicación al hacer que los cubos se desarrollen y volar, y al permitir que el jugador busque y destruya con un disparo láser..

1.1. Engendrando los elementos

Ya hemos establecido una posición inicial de la _SpawnController Según la rotación de la cámara del dispositivo. Ahora estableceremos un área alrededor de este punto donde se reproducirán nuestros cubos. Ahora vamos a actualizar el SpawnScript para hacer el _SpawnController crear una instancia de los elementos del cubo con diferentes tamaños y posiciones aleatorias, en relación con el _SpawnController.

Vamos a editar el SpawnScript clase, agregando algunas variables para controlar el proceso de desove.

SpawnScript de clase pública: MonoBehaviour // Elemento de cubo para generar GameObject mCubeObj público; // Qtd de cubos que se van a generar public int mTotalCubes = 10; // Tiempo para generar los cubos public float mTimeToSpawn = 1f; // mantener todos los cubos en el escenario privado GameObject [] mCubes; // define si la posición se estableció privado bool mPositionSet; 

Vamos a crear una coroutina llamada. SpawnLoop para gestionar el proceso de desove. También será responsable de establecer la posición inicial de la _SpawnController cuando el juego comienza Tenga en cuenta que el Random.insideUnitSphere Este método hace que los cubos se instalen en ubicaciones aleatorias dentro de un área esférica alrededor de la _SpawnManager.

clase pública SpawnScript: MonoBehaviour // Loop Spawning cube elements private IEnumerator SpawnLoop () // Definición de la posición de generación StartCoroutine (ChangePosition ()); rendimiento retorno nuevo WaitForSeconds (0.2f); // Generando los elementos int i = 0; mientras yo <= (mTotalCubes-1) )  mCubes[i] = SpawnElement(); i++; yield return new WaitForSeconds(Random.Range(mTimeToSpawn, mTimeToSpawn*3));   // Spawn a cube private GameObject SpawnElement()  // spawn the element on a random position, inside a imaginary sphere GameObject cube = Instantiate(mCubeObj, (Random.insideUnitSphere*4) + transform.position, transform.rotation ) as GameObject; // define a random scale for the cube float scale = Random.Range(0.5f, 2f); // change the cube scale cube.transform.localScale = new Vector3( scale, scale, scale ); return cube;  

Finalmente, edita el Comienzo() función. Asegúrese de quitar la  StartCoroutine (ChangePosition ());  línea y reemplazarlo con una llamada para iniciar el SpawnLoop coroutine.

SpawnScript de clase pública: MonoBehaviour void Start () // Inicializando el ciclo de inicio StartCoroutine (SpawnLoop ()); // Inicializar la matriz de cubos de acuerdo con // la cantidad deseada mCubes = new GameObject [mTotalCubes]; 

Ahora, de vuelta en Unity, tendrá que crear un prefab de cubo para crear una instancia del script.. 

  • Crea una carpeta llamada Prefabricados en el Proyecto ventana.
  • Cambiar el Cubo Escala de elementos en todos los ejes para 1 y cambiar la rotación a 0 en todos los ejes.
  • Arrastrar el Cubo al Prefabricados carpeta.
  • Eliminar el cubo de la Jerarquía ventana.
  • Selecciona el _SpawnController y arrastre el Cubo prefabricado de la Prefabricados carpeta a la M Cube Obj campo, ubicado en el SpawnScript area del inspector.


Finalmente, borra el Esfera ubicado dentro del _SpawnManager.

Ahora, si presionas jugar en Unity y ejecutas el proyecto en el dispositivo, deberías ver el desove de los cubos..

1.2. Cubos giratorios

Necesitamos agregar movimiento a esos cubos para hacer las cosas más interesantes. Rotemos los cubos alrededor de sus ejes y sobre el ARCamera. También sería genial agregar algún factor aleatorio sobre el movimiento del cubo para crear una sensación más orgánica.

Arrastrar el Cubo Prefab de la Prefabricados carpeta a la jerarquía.

  • Sobre el Guiones carpeta crear una nueva C # Script llamado CubeBehaviorScript.
  • Arrastra el Script a la Cubo prefabricar y abrirlo para editar.

Cada cubo tendrá características aleatorias. El tamaño, la velocidad de rotación y la dirección de rotación se definirán de manera aleatoria, utilizando algunas referencias definidas previamente. Vamos a crear algunas variables de controlador e inicializar el estado del cubo..

utilizando UnityEngine; utilizando System.Collections; clase pública CubeBehaviorScript: MonoBehaviour // Escala máxima / mínima de cubos public float mScaleMax = 2f; flotador público mScaleMin = 0.5f; // Orbit max Speed ​​public float mOrbitMaxSpeed ​​= 30f; // Orbit speed private float mOrbitSpeed; // Punto de anclaje para que el cubo gire alrededor de la transformación privada mOrbitAnchor; // Orbit direction private Vector3 mOrbitDirection; // Escala máxima de cubos Vector3 privado mCubeMaxScale; // Velocidad de crecimiento public float mGrowingSpeed ​​= 10f; bool privado mIsCubeScaled = falso; void Start () CubeSettings ();  // Establezca la configuración inicial del cubo Private void CubeSettings () // definiendo el punto de ancla como la cámara principal mOrbitAnchor = Camera.main.transform; // definiendo la dirección de la órbita float x = Random.Range (-1f, 1f); float y = Random.Range (-1f, 1f); float z = Random.Range (-1f, 1f); mOrbitDirection = nuevo Vector3 (x, y, z); // velocidad de definición mOrbitSpeed ​​= Random.Range (5f, mOrbitMaxSpeed); // definiendo la escala float scale = Random.Range (mScaleMin, mScaleMax); mCubeMaxScale = nuevo Vector3 (escala, escala, escala); // establece la escala del cubo en 0, para que crezca lates transform.localScale = Vector3.zero; 

Ahora es el momento de añadir algo de movimiento a nuestro cubo. Hagámoslo girar alrededor de sí mismo y alrededor del ARCamera, utilizando la velocidad y dirección aleatorias definidas anteriormente.

 // Se llama a Update una vez por fotograma. Update () // hace que la órbita del cubo gire RotateCube ();  // Hace que el cubo gire alrededor de un punto de anclaje // y gire alrededor de su propio eje privado Void RotateCube () // rote el cubo alrededor de la cámara transform.RotateAround (mOrbitAnchor.position, mOrbitDirection, mOrbitSpeed ​​* Time.deltaTime); // girando alrededor de su eje transform.Rotate (mOrbitDirection * 30 * Time.deltaTime); 

Para hacerlo más orgánico, el cubo se escalará desde el tamaño cero una vez que se haya generado.

 // Se llama a Update una vez por fotograma. Update () // hace que la órbita del cubo gire RotateCube (); // escalar el cubo si es necesario si (! mIsCubeScaled) ScaleObj ();  // Escala el objeto de 0 a 1 void privado ScaleObj () // growing obj if (transform.localScale! = MCubeMaxScale) transform.localScale = Vector3.Lerp (transform.localScale, mCubeMaxScale, Time.deltaTime * mGrowingSpeed); else mIsCubeScaled = true; 

2. Buscando y destruyendo

Esos cubos son muy felices volando así. ¡Hay que destruirlos con láseres! Vamos a crear un arma en nuestro juego y empezar a dispararles..

2.1. Disparando un laser

El disparo láser debe estar conectado a la ARCamera y su rotación. Cada vez que el jugador toque la pantalla del dispositivo, se disparará un láser. Usaremos el Física.Raycast clase para comprobar si el láser golpea el objetivo y si es así, le quitaremos algo de salud.

  • Crear un nuevo objeto vacío llamado _PlayerController y otro objeto vacío llamado _LaserController dentro de ella. 
  • Agrega un C # script llamado LaserScript dentro de Guiones carpeta y arrastrarlo a _LaserController.

Dentro LaserScript, usaremos un LineRenderer para mostrar el rayo láser, utilizando un punto de origen conectado a la parte inferior de la ARCamera. Para obtener el punto de origen del rayo láser, el cañón de la pistola virtual, obtendremos la cámara Transformar En el momento en que se dispara un láser y muévelo 10 unidades hacia abajo.. 

Primero, vamos a crear algunas variables para controlar la configuración del láser y obtener mLaserLine.

utilizando UnityEngine; utilizando System.Collections; clase pública LaserScript: MonoBehaviour public float mFireRate = .5f; flotador público mFireRange = 50f; flotador público mHitForce = 100f; public int mLaserDamage = 100; // Línea de representación que representará el láser privado LineRenderer mLaserLine; // Defina si la línea de láser está mostrando privado bool mLaserLineEnabled; // Hora en que las líneas del láser se muestran en la pantalla privada WaitForSeconds mLaserDuration = new WaitForSeconds (0.05f); // hora de hasta el siguiente incendio private float mNextFire; // Use esto para la inicialización void Start () // obteniendo el Line Renderer mLaserLine = GetComponent();  

La función encargada de disparar es Fuego(). Se llamará cada vez que el jugador presione el botón de disparo. Darse cuenta de Camera.main.transform se está utilizando para obtener el ARCamera Posición y rotación y que el láser se coloca 10 unidades por debajo de eso. Esto posiciona el láser en la parte inferior de la cámara..

// Dispare el láser privado vacío Fuego () // Obtenga ARCamera Transform Transform cam = Camera.main.transform; // Defina la hora del siguiente incendio mNextFire = Time.time + mFireRate; // Establecer el origen de RayCast Vector3 rayOrigin = cam.position; // Establezca la posición de origen de la Línea Láser // Siempre será 10 unidades por debajo de ARCamera // Adoptamos esta lógica por simplicidad mLaserLine.SetPosition (0, transform.up * -10f); 

Para verificar si el objetivo fue alcanzado, usaremos un Raycast.

// Disparar el láser privado vacío Fuego () // Mantener la información del golpe RaycastHit hit; // Comprueba si el RayCast golpeó algo si (Physics.Raycast (rayOrigin, cam.forward, out hit, mFireRange)) // Establezca el final de la línea láser en el objeto hit mLaserLine.SetPosition (1, hit.point) ;  else // Establezca el enfoque de la línea de láser para avanzar la cámara // utilizando el rango de láser mLaserLine.SetPosition (1, cam.forward * mFireRange); 

Por fin, es hora de verificar si se presionó el botón de disparo y llamar a los efectos del láser cuando se dispara el disparo..

// Se llama a la actualización una vez por fotograma nula Actualización () si (Input.GetButton ("Fire1") && Time.time> mNextFire) Fire ();  privado vacío Vacío () // código anterior suprimido por simplicidad // Mostrar el láser usando una Coroutine StartCoroutine (LaserFx ());  // Mostrar el privado de efectos láser IEnumerator LaserFx () mLaserLine.enabled = true; // Camino durante un tiempo específico para eliminar el rendimiento de LineRenderer mLaserDuration; mLaserLine.enabled = false; 

De vuelta en la unidad tendremos que añadir una LineRenderer componente a la _LaserController objeto.

  • Seleccionar _LaserController y en el Inspector ventana, haga clic en Agregar componente. Nombralo "Line Renderer"y seleccione el nuevo componente.
  • Crear una nueva carpeta llamada Materiales, y crear un nuevo material en su interior llamado Láser.
  • Selecciona el Láser Material y cambiarlo a cualquier color que te guste..
  • Selecciona el _LaserController y arrastre el material láser a la Materiales campo de la LineRenderer componente.
  • Todavía en LineRenderer, debajo Parámetros conjunto Empezar con a 1 y Terminar con a 0.

Si prueba el juego ahora, debería ver un láser disparado desde la parte inferior de la pantalla. Siéntase libre de agregar un Fuente de audio componente con un efecto de sonido láser para _LaserController para darle sabor.

2.1. Golpeando los cubos

Nuestros láseres necesitan golpear sus objetivos, aplicar daño y eventualmente destruir los cubos. Tendremos que añadir un Cuerpo rígido A los cubos, aplicándoles fuerza y ​​daño..

  • Arrastrar la Cubo prefabricar desde la carpeta de prefabs a cualquier lugar en el Escenario.
  • Seleccionar la Cubo y seleccione Agregar componente enla Inspector ventana. Nombra el nuevo componente "Cuerpo rígido"y selecciónelo.
  • Sobre el Cuerpo rígido conjunto de componentes Gravedad y Es cinemático a Apagado.
  • Aplicar esos cambios a la prefab..

Ahora vamos a editar el Comportamiento del cubo script para crear una función responsable de aplicar daño al cubo y otra para destruirlo cuando la salud cae por debajo de 0.

clase pública CubeBehaviorScript: MonoBehaviour // Cube Health public int mCubeHealth = 100; // Definir si el cubo está vivo bool privado mIsAlive = true; // Cube got Hit // devuelve 'false' cuando el cubo fue destruido public bool Hit (int hitDamage) mCubeHealth - = hitDamage; if (mCubeHealth> = 0 && mIsAlive) StartCoroutine (DestroyCube ()); devuelve verdadero  falso retorno;  // Destroy Cube IEnumerator privado DestroyCube () mIsAlive = false; // Hacer que el cubo desaparezca GetComponent() habilitado = falso; // esperaremos un poco antes de destruir el elemento // esto es útil cuando se usa algún tipo de efecto // como un efecto de sonido de explosión. // en ese caso, podríamos usar la duración del sonido como tiempo de espera y devolver el nuevo WaitForSeconds (0.5f); Destroy (gameObject); 

Bien, el cubo ahora puede tomar daño y ser destruido. Vamos a editar el LaserScript Para aplicar daño al cubo. Todo lo que tenemos que hacer es cambiar el Fuego() función para llamar al  Golpear método de la Comportamiento del cubo guión.

clase pública LaserScript: MonoBehaviour // Shot the Laser private void Fire () // código suprimido por simplicidad ... // Comprueba si RayCast golpeó algo si (Physics.Raycast (rayOrigin, cam.forward, out hit, mFireRange)) // Establezca el final de la línea láser en el objeto golpeado mLaserLine.SetPosition (1, hit.point); // Obtenga la secuencia de comandos CubeBehavior para aplicar el daño al CubeBehaviorScript de destino cubeCtr = hit.collider.GetComponent(); if (cubeCtr! = null) if (hit.rigidbody! = null) // aplica fuerza al hit hit.rigidbody.AddForce (-hit.normal * mHitForce); // aplicar daño al objetivo cubeCtr.Hit (mLaserDamage); 

3. Conclusión

¡Felicidades! ¡Nuestro juego de Realidad Aumentada está terminado! Sí, el juego podría ser más pulido, pero lo básico está ahí y la experiencia en general es bastante atractiva. Para hacerlo más interesante, puedes agregar una explosión de partículas, como hice en el video, y además de eso, puedes agregar un sistema de puntaje o incluso un sistema de ondas con un temporizador para que sea más desafiante. Los siguientes pasos son tuyos!

3.1. Que sigue?

Creamos un interesante experimento de AR usando Vuforia en Unity, sin embargo, todavía tenemos muchas características geniales que cubrir. No vimos ninguno de los recursos de Vuforia más sofisticados: objetivos, terreno inteligente, nube, etc. Manténgase atento a los siguientes tutoriales, donde cubriremos más de esas características, siempre utilizando el mismo enfoque paso a paso..

Te veo pronto!