3

I am using SteamVR and would like to rotate the camera based on the height that a controller has been raised, I have written the script that sends the the height of the controller through to a method on my camera script.

When I do the following, the rotation works:

transform.Rotate(0, 0, 30); // 30 is just to test, we will use the controller height later

But I would like to do this rotation slowly, this must not happen immediately.

I have also tried using Quaternion.Lerp, but it does not seem to be working.

Quaternion.Lerp(this.transform.rotation, new Quaternion(this.transform.rotation.eulerAngles.x, this.transform.rotation.eulerAngles.y, zPosition, 0), Time.deltaTime * 5);

Any suggestions?

Serlite
  • 12,130
  • 5
  • 38
  • 49
Chrisjan Lodewyks
  • 1,162
  • 4
  • 13
  • 25
  • Which function do you have this in? – Andrew_CS Mar 07 '17 at 20:48
  • This is being called from the update of my Controller script, if the height is greater than my threshold, I call this function to rotate to a increment of the height. – Chrisjan Lodewyks Mar 07 '17 at 21:00
  • 1
    You want to rotate incrementally, 90 degrees, in the Z axis? – Programmer Mar 07 '17 at 21:03
  • Yes, as if I were turning my head sideways. `transform.Rotate(0, 0, 30);` rotates it correctly, but the below rotates is as if I were looking directly right. `Vector3 direction = new Vector3(0, 0, 30); Quaternion targetRotation = Quaternion.Euler(direction); this.transform.rotation = Quaternion.Lerp(this.transform.rotation, targetRotation, Time.deltaTime * 2);` – Chrisjan Lodewyks Mar 07 '17 at 21:05
  • 1
    Can you try the `RotateObject` function from [this](http://stackoverflow.com/a/41651803/3785314) answer? – Programmer Mar 07 '17 at 21:08
  • @Programmer, see my answer posted below. Thank you for the help. :) – Chrisjan Lodewyks Mar 07 '17 at 21:16
  • Good. As long as your problem is solved. – Programmer Mar 07 '17 at 21:19

2 Answers2

6

Quaternion.Lerp() should work fine for your needs - however, your usage of it supplies some incorrect parameters to the method, which is why it wasn't working as expected. (Also, you probably shouldn't be constructing a Quaternion using its constructor, there are helper methods to properly convert from Euler angles.)

What you need to do is record the initial starting and ending rotations, and pass them into Quaternion.Lerp() every time you call it. Note that you can't just reference transform.rotation every frame, because it will be changing as the object rotates. For example, adjusting your code to work:

Quaternion startRotation;
Quaternion endRotation;
float rotationProgress = -1;

// Call this to start the rotation
void StartRotating(float zPosition){

    // Here we cache the starting and target rotations
    startRotation = transform.rotation;
    endRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, zPosition);

    // This starts the rotation, but you can use a boolean flag if it's clearer for you
    rotationProgress = 0;
}

void Update() {
    if (rotationProgress < 1 && rotationProgress >= 0){
        rotationProgress += Time.deltaTime * 5;

        // Here we assign the interpolated rotation to transform.rotation
        // It will range from startRotation (rotationProgress == 0) to endRotation (rotationProgress >= 1)
        transform.rotation = Quaternion.Lerp(startRotation, endRotation, rotationProgress);
    }
}

Hope this helps! Let me know if you have any questions.

Serlite
  • 12,130
  • 5
  • 38
  • 49
  • I used more or less the same in my answer below, your answer is a lot more complete so I marked it correct. Thank you for the in detail help. – Chrisjan Lodewyks Mar 07 '17 at 21:27
  • Thanks! It seems you were finding your own solution as I was writing up my answer - I hope it at least helped flesh out your knowledge in this area. – Serlite Mar 07 '17 at 21:33
5

If anyone else comes across this, I got mine working using the below code:

Vector3 direction = new Vector3(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, -30);
Quaternion targetRotation = Quaternion.Euler(direction);
this.transform.rotation = Quaternion.Lerp(this.transform.rotation, targetRotation, Time.deltaTime * 1);
Chrisjan Lodewyks
  • 1,162
  • 4
  • 13
  • 25