Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Cardboard] First Person Controls (i.e. Rotate with Right Stick)

Discussion in 'AR/VR (XR) Discussion' started by Indemonai_Games, Jul 21, 2015.

  1. Indemonai_Games

    Indemonai_Games

    Joined:
    Jul 20, 2015
    Posts:
    9
    Hi everyone. This one is giving me a headache here... So I have a custom first person script, and it works great with a controller if not using the Cardboard SDK.

    The thing here is, I can rotate the player object to always face the "Head" object of the Cardboard SDK, and that works great too and I can move around without using the Right Stick. But I want people to be able to rotate the camera left or right using the stick as well, in case they don't have much space to move around in real life.

    The problem is that I can't rotate the "Head" Object through code at all. I want the player to always go in the direction they are looking, regardless of if they are using their heads or the right stick, but I can't make that work, only the head or the stick, not both.

    Any ideas? I've tried a lot of stuff with no results...

    Here's the script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerController : MonoBehaviour
    5. {
    6.     public GameObject playerCamera;
    7.  
    8.     public float walkSpeed = 5f;
    9.     public float runSpeed = 15f;
    10.     public float speed = 0f;
    11.  
    12.     public float mouseSensitivity = 15f;
    13.  
    14.     public bool bYInvert = false;
    15.     public bool bCardboard = false;
    16.  
    17.     void FixedUpdate()
    18.     {
    19.         float moveHorizontal = Input.GetAxis("Horizontal") * speed * Time.deltaTime;
    20.         float moveVertical = Input.GetAxis("Vertical") * speed * Time.deltaTime;
    21.  
    22.         float mouseHorizontal = Input.GetAxis("Mouse X") * mouseSensitivity;
    23.         float mouseVertical = Input.GetAxis("Mouse Y") * mouseSensitivity;
    24.  
    25.         if (!bCardboard)
    26.         {
    27.             transform.Rotate(0, mouseHorizontal, 0);
    28.             playerCamera.transform.Rotate(-mouseVertical, 0, 0);
    29.         }
    30.         else
    31.         {
    32.             // ??? No clue!
    33.         }
    34.  
    35.         transform.Translate(-moveVertical, 0, moveHorizontal);
    36.  
    37.         if (Input.GetButton("Run") && moveVertical >= 0)
    38.         {
    39.             if (speed != runSpeed)
    40.             {
    41.                 speed = Mathf.MoveTowards(speed, runSpeed, 0.5f);
    42.             }
    43.         }
    44.         else
    45.         {
    46.             if (speed != walkSpeed)
    47.             {
    48.                 if (moveVertical >= 0)
    49.                 {
    50.                     speed = Mathf.MoveTowards(speed, walkSpeed, 0.25f);
    51.                 }
    52.                 else
    53.                 {
    54.                     speed = walkSpeed;
    55.                 }
    56.             }
    57.         }
    58.     }
    59. }
     
  2. dolims

    dolims

    Joined:
    Sep 13, 2014
    Posts:
    61
    The Head object's transform gets overwritten each frame based on the gyro reading. I'd suggest using the stick to control the parent object of the Head, or a separate target object (set the Head's target property to point at it).
     
    Mycroft likes this.
  3. Indemonai_Games

    Indemonai_Games

    Joined:
    Jul 20, 2015
    Posts:
    9
    @dolims
    Thank you for your reply. The problem here is that I also want the parent object (my char script + collision) to rotate to where the head is looking + rotate if the right stick is used. I can easily make it so the right stick rotates the character and you just use the head to look around, and I think it is a good control scheme, but I was envisioning it as I said before, and I would like to at least achieve it and try it and see what it feels like, but I have no idea how to do it...
     
  4. dolims

    dolims

    Joined:
    Sep 13, 2014
    Posts:
    61
    Taking a different tack, if you want to move the player in the direction the user is looking, then get the Head's forward vector, and always move the body in that direction.

    // Good for flying
    body.transform.position += speed * Head.transform.forward;

    // Good for moving along the ground
    Vector3 facing = Head.transform.forward;
    facing.z = 0;
    body.transform.position += speed * facing.normalized;

    Now, use the stick to rotate the body, and let the Cardboard SDK rotate the head.
     
  5. Indemonai_Games

    Indemonai_Games

    Joined:
    Jul 20, 2015
    Posts:
    9
    @dolims

    Sorry for the late reply. Thank you for your input, unfortunately I had tried that before and it doesn't work, because the Head does not rotate with the parent object, it has it's own rotation. So if I rotate the camera (let's say it's now 40º to the right) with the stick and press forward, I would go 40º to the left, because the Head's rotation in Y hasn't changed at all.
     
  6. dolims

    dolims

    Joined:
    Sep 13, 2014
    Posts:
    61
    The Head rotation is relative to its parent unless you set a separate target gameobject for it to be relative to. Or am I misunderstanding your scene setup?
     
  7. Indemonai_Games

    Indemonai_Games

    Joined:
    Jul 20, 2015
    Posts:
    9
    @dolims

    That's what it should do, but it doesn't. The head object's rotation does not update with the parent object. If I rotate the parent, the Head remains at (0, 0, 0) until I rotate that. I have no target assigned. This was off putting as I never saw this behavior in Unity but I guess it's because the Head's rotation is controlled solely by the gyroscope.
     
  8. dolims

    dolims

    Joined:
    Sep 13, 2014
    Posts:
    61
    Can you check that your CardboardHead script has code like this:

    var rot = Cardboard.SDK.HeadPose.Orientation;
    if (target == null) {
    transform.localRotation = rot;
    } else {
    transform.rotation = rot * target.rotation;
    }

    The CardboardHead object's localRotation is set to the gyro orientation, so the gameobject's orientation should be relative to the parent. If you use this object's transform.forward, it will include both the user's head rotation, and any rotation of the parent gameobject (which you can control with the stick).
     
  9. Indemonai_Games

    Indemonai_Games

    Joined:
    Jul 20, 2015
    Posts:
    9
    @dolims

    Thank you for your reply. I'll check that out later today as I just formatted my computer.
     
  10. plysaght47

    plysaght47

    Joined:
    Jul 2, 2015
    Posts:
    21
    Did you ever figure this out? I'm working through the same issue at the moment.
     
  11. dolims

    dolims

    Joined:
    Sep 13, 2014
    Posts:
    61
    Reading back over the thread, I'm not sure I got an exact understanding of the original problem. There was a bug in CardboardHead that showed up if target != null, which is fixed in the recent SDK update (v0.5.2).

    Can you describe your gameobject setup? Which GO do you move by controller, which one has the CardboardHead script, what your target GO is (if any)?
     
  12. plysaght47

    plysaght47

    Joined:
    Jul 2, 2015
    Posts:
    21
    I'm trying to set up first person controller, moved by joystick input, and setting the rotation of the player to the rotation of the Head Tracking.

    I have tried multiple ways to accomplish this. I started with making the CardboardHead prefab a child of my player(capsule) object, then attaching the movement script to the capsule, and then setting the rotation of the capsule equal to the rotation of the underlying Head rotation. I've also tried to do this without the use of a player, and instead stuck the movement script and rotation directly onto the camera.

    I got it to partially work where the rotation was reset, and my user inputs would steer me according to rotation of the head...however, as soon as I rotated at all, the camera will not stop spinning.

    I've tried raycasting, I've tried setting the target...again multiple attempts. And also as an fyi, I've only been developing and coding for about 4 months.

    Long story short, I need a way to move my player, and set the player rotation to the head tracking, so forward is always where the person is looking, backward is backward, etc.
     
  13. joostbos

    joostbos

    Joined:
    Feb 4, 2015
    Posts:
    63
    @plysaght47 Can you give a little more explanation on how you finally achieved what you were aiming for. I am trying to do the same (move the player by joystick, rotate using head-tracking). I am trying to achieve it by adapting the MouseLook functionality, but like you described, once I turn the character keeps spinning.

    Did you use the standard FPSController prefab and script?
     
  14. three2wan

    three2wan

    Joined:
    Jul 28, 2015
    Posts:
    25
    joostbos, i'm also having that kind of problem. are you able to solve it?

    plysaght47, can you show me how you solve it?
     
  15. plysaght47

    plysaght47

    Joined:
    Jul 2, 2015
    Posts:
    21
    Forgot I posted to this thread...my apologies. What I finally settled upon for my Cardboard VR game (Demon Maze VR available on the google play store), was head based steering, using a navmesh, agent, and event system. When my gaze pointer intersects part of the navigation area, a event is triggered to send the nav agent to that location.

    As far as the joystick input to move a character, and have head movement control the rotation of the player, I still haven't figured that out and I must have been having a nutty professor moment when I posted on October 21, 2015...boggling my mind right now as to what the heck I was talking about.

    Anyway, right now I have moved onto developing for GearVR and again, face the same issue. If you child your main camera to an object then move the object, the camera will move fine. However, when you rotate your head(camera), the direction of the object does not rotate obviously. I'm still stuck...I've just downloaded the Quaternion PID Controller and I will post if this is of any help.

    Some games I have downloaded on GearVR seem to use the recenter method, but that seems to only be with games that are moving you in one direction to start out...so again not that helpful.
     
    seyed_mostafa likes this.