0
votes

I have a Unity game with landscape orientation. I want to be able to rotate the camera to the left and to the right. More, I want to move the camera back and forward according to the gyro tilt in the y-axis, and the total vector of rotating right or left. In other words, I want to be able to move the camera like a person walking in a room. The camera is the main player of my game.

This is what I tried to do:

GameObject CamParent;
Rigidbody RB;

void Start()
{

    CamParent = new GameObject("CamParent");
    CamParent.transform.position = this.transform.position;
    this.transform.parent = CamParent.transform;
    Input.gyro.enabled = true;
    RB = this.GetComponent<Rigidbody>();
}

void Update()
{
    CamParent.transform.Rotate(0, -Input.gyro.rotationRateUnbiased.y, 0);
    this.transform.Rotate(-Input.gyro.rotationRateUnbiased.x, 0,0);
    float Z = -Input.gyro.userAcceleration.z;
    RB.AddForce(new Vector3(0,0,Z)*10);
}
1
I'm not sure I understand what you are trying to do, but wouldn't it make more sense to add a rigid body to the camera parent, and add the force to that instead of adding a force directly to the camera? Otherwise as the camera moves from its original position, the effect of rotating the camera parent will change. - lockstock

1 Answers

2
votes

I've attempted to answer your question as best I can, as your question was a little bit unclear to me.

First and foremost, since you are using forces and physics, you should be using the void FixedUpdate() function rather than the void Update() function. This will ensure that your code is executed at uniform intervals, which is very important when dealing with physics.

I am also unsure as to why you instantiated a new GameObject. You can simply add this script to a Camera GameObject in Unity and then add a Rigidbody component to the Camera as well. This will simplify your Start() function, which should only contain these two lines:

Input.gyro.enabled = true;
RB = gameObject.GetComponent<Rigidbody>();

Next, it is important to note that the Quaternion returned from the Input.gyro.attide has left-handed coordinates, whereas Unity has right-handed coordinates. This conversion from Gyroscope to Unity can be accomplished with the following function:

Quaternion GyroToUnity(Quaternion quat)
{
    return new Quaternion(quat.x, quat.z, quat.y, -quat.w);
}

I'm sure there are other ways to accomplish this conversion, but this way works for me.

Now let's deal with the Camera's rotation. Start by setting the Camera's rotation by setting the camera's transform.rotation equal to the Quaternion you just converted from Gyroscope. There's one more problem, however, since Gyroscope z-axis points in the same direction as Unity's y-axis. This can be fixed by simply executing transform.Rotate(90,0,0);. Finally, we set the rotation of the Camera using this line of code:

transform.rotation = Quaternion.Euler(new Vector3(0f, transform.rotation.eulerAngles.y, 0f));

Last we must handle adding a force to the Camera. I'm not sure exactly how you want movement to be handled, but I assumed you wanted movement about the z-axis with respect to the Camera's rotation. To do this you need to use the AddRelativeForce(Vector3 relativeForce) from the Rigidbody component on the camera.

However, to determine the direction of force, we must access the degree of rotation about the x-axis from Quaternion we converted to Unity earlier. yourQuat.eulerAngles.x, which returns a float such that 0 <= x < 360. With the way the we oriented the the Camera's coordinate system, facing straight forward with your iOS device should return a value of roughly 0.0. While I was played around with this question, I found that this code adequately directed the camera:

Vector3 relativeForce;
if (yourQuat.eulerAngles.x > 315 || yourQuat.eulerAngles.x < 90)
    relativeForce = Vector3.forward;
else if (yourQuat.eulerAngles.x < 315)
    relativeForce = Vector3.back;
else
    relativeForce = Vector3.zero;

Finally take the subsequent Vector3 value and use like so

RB.AddRelativeForce(relativeForce);

Hope that helps. If this is not the exact functionality you were looking for, this should get you a good start to fine tune your program to do exactly what you want.