Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Necesito ayuda para mi 1st person VR, el giro de la camara VR no afecta a la trayectoria del desplazamiento

Iniciado por DaniVR, Junio 14, 2017, 06:55:06 PM

Tema anterior - Siguiente tema
Hola a todos.
 
Estoy aprendiendo a hacer un script para controlar el movimiento de mi personaje en VR. He conseguido hacer que se desplace bien, pero no consigo que al mover mi camara de VR (Cardboard), el giro afecte a la trayectoria del desplazamiento.
 
Necesito ayuda para crear el codigo, que me tome los valores de la posicion de la camara VR (supongo que creando un Vector3 que dice donde esta el frente) y luego coger ese valor y ponerselo al desplazamiento, para que tenga una referencia de donde esta el frente, y que cada vez que giro la cabeza, el desplazamiento sea en la nueva direccion a la que estoy mirando.
 
Supongo que habra muchas maneras de hacerlo, otra que se me ha ocurrido es coger los valores de posicion de la camara en cada frame, y asignarselos a un dummy que tenga como padre, que es el que recoge los valores de posicion de la camara VR (ya que en el ultimo sdk de googleVR dicen que ahora el movimiento de la camara solo esta permitido a traves de un parent, del que la camaraVR sea el child), luego coger los valores de posicion de ese dummy y hacer que la capsula que uso como player, tome los valores de rotacion del eje Y del dummy y se los aplique a la capsula, que tiene el control de movimiento.
 
 
 
El problema es que no soy programador, y con lo poco que se, y lo que cambian el sdk de googleVR, pues no encuentro como hacerlo. Por cierto me a dado la sensacion de que google quiere dejar de lado a Cardboard, y darle todo el protagonismo a daydream. Me ha costado muchisimo hacer que me funcione Cardboard en mi tlf, he tenido que rootear y ponerle la ultima version, o si no... olvidate...
 
 
 
Me podriais ayudar alguno a conseguir por fin un 1st person controller que me funcione en RV, necesito ayuda para recoger los datos de posicion de la camara VR, y asignarselos al desplazamiento, para poder tener un movimiento correcto.
 
 
 
Este es mi codigo, he comentado todo lo relativo a mis intentos de asignar la camara Vr, y he dejado solo lo relativo al desplazamiento.
 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MiVR2 : MonoBehaviour {
    public float speed = 3.0f;
    //public Transform vrCamera;
    GameObject player;
    // Use this for initialization
    void Start () {
    
 
    }
    // Update is called once per frame
    void Update () {
        //Vector3 forward = vrCamera.TransformDirection (Vector3.forward);
        float translation = Input.GetAxis ("Vertical") * speed;
        translation *= Time.deltaTime;
        //translation *= forward;
        float straffe = Input.GetAxis ("Horizontal") * speed;
        straffe *= Time.deltaTime;
 
        transform.Translate(straffe, 0, translation);
    }
}

 
 
 
A ver si me podeis ayudar a solucionarlo, ya que es un problema en el que llevo mucho tiempo atascado, y que ya me ha hecho apartarme de unity durante una temporada, me gustaria aprender a hacer esto, para poder avanzar en mis proyectos.
 
 
 
Por cierto , el setup del 1st personVR, es una capsula con el script de movimiento, tiene un hijo que es el dummy de la camara VR (para poder mover la camara, segun el ultimo sdk), y dentro de este dummy hay otro hijo que es la camaraVR.
 
 
 
Gracias y un saludo

Buenas Dani.
 
Como comentas hay infinidad de maneras de realizar el movimiento que quieres implementar, una de las maneras que se suelen usar y es bastante sencillo es ponerle al player un Charactercontroller, ya con eso se crea un simple movimiento hacia adelante y solucionado.
 
 
 

public class vrmove : MonoBehaviour {
   
    public float speed = 3.0F;
    // Should I move forward or not
    public bool moveForward;
    // CharacterController script    
private CharacterController controller;
    // GvrViewer Script
    // VR Head
    private Transform vrHead;
 
    // Use this for initialization
    void Start()
    {
 
        // Find the CharacterController
        controller = GetComponent<CharacterController>();
        // Find the GvrViewer on child 0
        // Find the VR Head
        vrHead = Camera.main.transform;
    }
    // Update is called once per frame
    void Update()
    {
        // In the Google VR button, or the Gear VR touchpad is pressed
        if (Input.GetButtonDown("Fire1"))
        {
            // Change the state of moveForward
            moveForward = !moveForward;
        }
        // Check to see if I should move
        if (moveForward)
        {
            // Find the forward direction
            Vector3 forward = vrHead.TransformDirection(Vector3.forward);
            // Tell CharacterController to move forward
            controller.SimpleMove(forward * speed);
        }
    }
 
}

 
 

Hola J4v1
 
 
 
Gracias por tu aporte, me ha sido muy util, sobre todo para coger la posicion de la camara.
 
He conseguido hacer lo que pretendia, pero ahora tengo un pequeño problema...
 
Ahora me junto con dos vectores, uno para la posicion de la camaraVR, y el otro vector me da el desplazamiento que realizo con el joystick.
 
El problema viene a la hora de sumarlos, funciona, pero me provoca una pequeña aceleracion el vector de la camara VR, con lo que hay un movimiento indeseado, que es sumado al vector que lleva el movimiento del gamepad. Lo que me gustaria seria anular el movimiento que me añade el vector de la camara VR, y dejarlo a 0, respetando la orientacion. Y moverme con los valores que le añado con el otro vector.
 
Supongo, que tendria que hacer de otra manera la variable midireccion, para moverme correctamente. Podriais ayudarme alguno con eso?
 
Os pego el script para que lo veais mas claro:
 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MiVR7 : MonoBehaviour {
 
public float speed = 3.0F;
// Should I move forward or not
//public bool moveForward;
// CharacterController script  
 
private Vector3 moveDirection = Vector3.zero;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 midireccion = Vector3.zero;
private CharacterController controller;
// GvrViewer Script
// VR Head
public Transform vrHead;
// Use this for initialization
void Start () {
   // Find the CharacterController
   controller = GetComponent<CharacterController>();
   
   // Find the VR Head
   vrHead = Camera.main.transform;
}
// Update is called once per frame
void Update () {
   if (controller.isGrounded) {
      moveDirection = new Vector3 (Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
      moveDirection = transform.TransformDirection (moveDirection);
      moveDirection *= speed;
      if (Input.GetButton ("Jump"))
         moveDirection.y = jumpSpeed;
   }
   moveDirection.y -= gravity * Time.deltaTime ;
 
   // Find the forward direction
   Vector3 forward = vrHead.TransformDirection(Vector3.forward);
   midireccion = forward + moveDirection;
   
   controller.Move(midireccion * Time.deltaTime);
 
}
}

 
Gracias y un saludo

Tambien estoy intentando hacerlo de otra manera, seria cogiendo el transform de vrHead, y asignandoselo a la capsula que lleva el script de movimiento. Para que la capsula y el vrHead tengan la mismo posicion en un principio (subiria el codigo de "
 

// Find the forward direction
   Vector3 forward = vrHead.TransformDirection(Vector3.forward);

 
" )
 
para situarlo antes de darle las ordenes con el gamepad.
 
Lo he intentado de muchas maneras y me ha dado muchos errores, me gustaria saber como la hariais vosotros.
 
Yo trato de igualar el transform local con el transform del vrHead, con algo asi 
 



   
      GameObject.transform  = forward;
   

[/quote]
 
porque se supone que en el forward va el vector con los datos de la vrHead, y asi se lo estaria asignando al gameobject local , que seria la capsula. Pero no funciona.
 
Tambien he probado con:
 



   
      transform.localRotation = GameObject.vrHead.transform;
   

[/quote]
 
Pero no consigo que funcione.
 
Podéis ayudarme alguno?
 
Gracias
 
 

Me sabe mal Dani pero mi nivel de programar no esta muy alto, intentare echarle un ojo este finde a ver si te puedo sacarte el codigo que necesitas, pero me tocara hacer algunas pruebas,el código que te pase si se que funcionaba porque es el que uso yo para el desplazamiento de las Cardboard :D

Hola J4v1
 
 
 
Tu nivel de querer ayudar es... elevadisimo!!   asi que, muchas gracias por estar aqui.
 
 
 
Me gustaria muchisimo tener un 1st controler para RV que funcionara bien, con un gamepad. Y que no tuviera el problema de que al girar la vista mientras andas hacia delante, no cambie del mismo modo la trayectoria del desplazamiento.
 
Asi que, si consigues lograrlo el finde te estaria muy agradecido. Y sino ya solo con la ayuda y apoyo que me has dado, sera suficiente. Y lo acabare consiguiendo de un modo u otro.
 
Yo soy artista 3D y esto de lo programacion, lo llevo fatal, se lo que quiero hacer pero no se como decirselo al programa. Si tu me ayudas con esto, yo podria hacerte algun modelo que necesites, o pasarte el escenario que estoy haciendo para que lo uses en tus pruebas por si puede servirte de algo.
 
Bueno, te cuento un poco, como lo tengo puesto para que no pierdas tiempo buscando la informacion por ahi:
 
Uso la version de Unity 2017.1.0b, esta version, lleva integrada la Rv de cardboard y daydream, solo necesitas activarla en Player settings, marcando Virtual Reality suported, y eliges Cardboard en el desplegable. Asi Unity crea la camara estereoscopica sin necesidad de sdk de terceros. OJO que en esta version al darle al play, aunque este en estereoscopico, te lo va a mostrar en el visor como si solo fuera monoscopico (una camara), pero luego al hacer la build para andriod, si que se vera estereoscopico.
 
Luego ademas tengo puesto el SDK de GoogleVR para Unity, la ultima version es la 1.60, que cambia bastante respecto a la 1.5.
 
Basicamente solo uso un prefab de ese sdk de google, que es el GRVeditorEmulator en prefabs, que lo que hace es que al arrastrarlo a la jerarquia y ponerlo en escena, puedes simular el movimiento de headtracking del movil si pulsas la tecla ALT+desplazar el raton. Asi te evitas tener que compilar cada vez, y puedes comprobarlo en el editor.
 
Si logras hacer un 1stControlerVR, que al girar con la cabeza, la trayectoria del desplazamiento que llevas, gire en consecuencia, al pulsar alt en el editor, entonces lo habras conseguido.
 
Segun la ultima version de Unity, no puedes controlar el movimiento de la camara VR directamente, tienes que usar un padre. Aqui tienes mas informacion, mira en el apartado de :
 
https://docs.unity3d.com/Manual/VROverview.html
 
 
 



   


      Understanding the camera
   


   
      The Camera Transform is overridden with the head-tracked pose. To move or rotate the Camera, attach it as a child of another GameObject. This makes it so that all Transform changes to the parent of the Camera affect the Camera itself. This also applies to moving or rotating the camera using a script.
   

[/quote]
 
Debido a eso, la configuracion para montar el 1stcontrolerVR mas acertada, creo que seria:
 
Crear un Gameobject empty, llamado VRCam (que sea el dummy al que le vamos a meter el giro de la camara, con nuestro movil y que lleva tambien el script de movimiento).
 
Tendria dos childs:
 
-uno seria la camara normal (que no podemos mover, solo a traves del dummy)
 
-el otro seria la capsula con el collider, que seria el jugador.
 
Lo primero que haria seria, coger los datos de hacia donde apunta nuestro visor, con un vector. Y darle ese vector a nuestro dummy VRCam. Y cuando lo tenga, le damos el movimiento a traves de otro vector.
 
Para coger los datos hacia donde apunta nuestro visor, puedes usar:
 
defines primero la posicion del transform del objeto que contiene el script, con 
 



   
       
   
   
      public Transform vrHead;
   
   
      //En el update, pones esto
   
   
      Vector3 forward = vrHead.TransformDirection(Vector3.forward);
   
   
       
   

[/quote]
 
Luego en el editor, no te olvides de arrastrar la camara al vrHead del scrip en el editor, y asi obtienes su transform.
 
Y asi tienes un Vector llamado Forward con los datos de hacia donde estamos mirando. Lo siguiente seria asignar esa informacion a nuestro VRCam, el dummy, para que se coloque en esa posicion (aunque ya deberia de estar ahi colocado con el public Transform vrHead; )
 
Y es aqui donde fallo.
 
 
 
Para el movimiento, estoy usando esto:
 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MiVR8 : MonoBehaviour {
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
public Transform vrHead;

   // Use this for initialization
void Start () {
   //controller = GetComponent<CharacterController>();
   // Find the GvrViewer on child 0
   // Find the VR Head
   vrHead = Camera.main.transform;
   
}
// Update is called once per frame
void Update () {
   CharacterController controller = GetComponent<CharacterController>();
   Vector3 forward = vrHead.TransformDirection(Vector3.forward);
             
   if (controller.isGrounded) {
      moveDirection = new Vector3 (Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
      moveDirection = transform.TransformDirection (moveDirection);
      moveDirection *= speed;
      if (Input.GetButton ("Jump"))
         moveDirection.y = jumpSpeed;
   }
   moveDirection.y -= gravity* Time.deltaTime ;
   controller.Move (moveDirection * Time.deltaTime);
   
}
}

 
 
 
La clave de todo, estaria en antes de aplicarle el movimiento, coger los datos de hacia a donde estamos mirando, con el vector forward, y asignarle esa transform, o posicion, o rotacion, a nuestro dummy VRCam. Y cuando este correctamente encarado, aplicarle el movimiento.
 
Lo mas cerca que he estado de conseguirlo, ha sido con estos 2 vectores el de la camara (forward) y el del gamepad o teclado (moveDirection).
 
Lo que hice fue crear un tercer vector, llamado midireccion y hacer:
 



   
       
   
   
      midireccion = forward + movedirection;
   
   
      //y editar la ultima linea, y poner:
   
   
      controller.Move (midireccion * Time.deltaTime);
   
   
       
   

[/quote]
 
Y esto si conseguia lo que yo queria, lo malo es que el vector de forward le añade un pequeño desplazamiento a la direccion, y aunque no pulses ningun eje en el gamepad, el 1stcontrolerVR se mueve.
 
Luego si pulsas el stick analogico o las flechas del teclado, ademas le añade el movimiento esperado en la direccion esperada. Y respetando la direccion en la que estamos mirando al desplazarnos.
 
Lo suyo seria, que ese primer vector forward, no le añadiera ningun desplazamiento, solo la orientacion.
 
 
 
Bueno seguire intentandolo y esperando alguna noticia tuya, a ver si has tenido suerte durante el fin de semana.
 
A ver si algun programador mas experimentado, se anima y nos echa una mano. Ya que esta es una duda que parece que va a tener mucha gente, estaria muy bien tener aqui la solucion. Y no parece demasiado complicada, pero a mi se me escapa.
 
 
 
Gracias y un saludo
 
 
 
 

Hola,
 
Yo estoy en las mismas, la cuestion es que con la version anterior de Unity, la 5, logré hacerlo a traves de un tuto de youtube, lo pongo si lo quieres. No se si habrás logrado dar con la solución. Si es así y puedes compartirla seria de agradecer.
 
Saludos.
 
Jesus

Hola MegaPRO
 
Estaria bien, tener el link al tutorial que dices, todo lo que sea tener mas informacion siempre ayuda. Aunque con la ultima version del SDK de GoogleVR, cambiaron la manera de manejar la camara virtual, y supongo que los tutos que hay seran para versiones anteriores.
 
No he conseguido avanzar nada con este problema, asi que deje de intentarlo y aparte el Unity durante una temporada. Ahora de nuevo, me esta entrando el gusanillo, y mirare a ver si consigo avanzar algo, o si hay algun tutorial en el que lo expliquen bien, para las ultimas versiones de GoogleVR. 
 
Si consigo algun avance lo pondre por aqui.
 
Y si alguien al que se le de bien la programacion, se anima a ayudarnos pues le estaria muy agradecido, y seguro que mas gente que en el futuro tendra este problema, tambien se lo agradeceria.
 
 
 
Un saludo

Cita de: DaniVR date=1505701622Hola MegaPRO
   
   
      Estaria bien, tener el link al tutorial que dices, todo lo que sea tener mas informacion siempre ayuda. Aunque con la ultima version del SDK de GoogleVR, cambiaron la manera de manejar la camara virtual, y supongo que los tutos que hay seran para versiones anteriores.
   
   
      No he conseguido avanzar nada con este problema, asi que deje de intentarlo y aparte el Unity durante una temporada. Ahora de nuevo, me esta entrando el gusanillo, y mirare a ver si consigo avanzar algo, o si hay algun tutorial en el que lo expliquen bien, para las ultimas versiones de GoogleVR. 
   
   
      Si consigo algun avance lo pondre por aqui.
   
   
      Y si alguien al que se le de bien la programacion, se anima a ayudarnos pues le estaria muy agradecido, y seguro que mas gente que en el futuro tendra este problema, tambien se lo agradeceria.
   
   
       
   
   
      Un saludo
   


Hola,
 
Por alguna razón no me avisó el notificador y he visto ahora este mensaje Dani, este es el tutorial,
 


   
tart=254&feature=oembed" width="480">

 
De todas formas como bien dices, si estas ya trabajando con la versión de Unity3D 2017, el propio FirstPerson del Character Assets, ya lo hace por defecto.
 
Un saludo.
 
 
 
Jesus.

Etiquetas: