Rotating Camera in FPSInputController to a defined point

Here’s the goal:

Player in first person game clicks on point of interest. The camera swings to face that point (as in, say, a LookAt() or a Quaternion.Lerp()) and in the meantime the player can’t move the camera using the mouse. After the event happens, the camera should remain in that exact orientation when the player regains control of the mouse (after, say, an event, minigame, or cutscene occurs), and smoothly continues playing the game.

I have most of this. I’m using the default FPSInputController. I click on an object (raycasting to find it, grabbing its position, using that to inform a Quaternion LERP over time, etc.), the camera smoothly swerves to focus the clicked object in the center of the screen. Stuff happens. The player can’t mouse around while the stuff is happening. All that works fine. Then I give control back, and the problems are such:

*Moving the camera explicitly this way doesn’t reorient the player object, so the camera no longer looks “straight”, leaving the FPSController to move drunkenly sideways or backwards relative to where you’re looking.

*The camera has also been known to “jump” once the player regains control of the camera, the orientation isn’t the same as the point I LERPed to. The motion is smooth except for one jarring frame where clearly the camera is changing between two obviously different quaternions.

In a nutshell, I need a way to reorient the FPS character to be facing where I set the camera orientation in code, without any twitching, and making sure the camera still looks in the proper direction when the player can move again.

I am setting the camera’s orientation outside of the main FPSController scripts (motor, mouselook, etc.) in another script object, which I’m sure is a factor.

I’ve tried a few hacky solutions, which are just close enough to working that the error is infuriating, but some code listing the specific objects to set in the proper order with the right functions would be nice! I’m sure its a matter of hierarchy, any help would be appreciated!

Working through, one problem is that LookAt will turn the camera, but the direction of the character motor won’t change with it. I actually have it so that the camera “resets” back to where the motor was facing, but ideally I’d like to do the opposite. Is there an elegant way I can explicitly set the FPS controller motor rotation from another script?

That way, as I LERP the camera to where I want the player to look, the motor it’s connected to should turn with it, or at least be set when the camera is done - without warping where the camera is. It might sound backwards but is there a good way to do this?

Got it. Since I was using the default FPS controller, I had to tweak a few places:
-I had a flag telling the mouselook if it was active or not. The variable “rotationY” in particular should still be set each update while the camera is being LERPed, this is basically to have the rotationY Euler angle keep up with the quaternions I’m using in the LERP code, so that when they’re done the Eulers (hopefully) will express the same transform.rotation:

//added to Mouselook
if (canLook == false)
{
momentum.x = 0;
momentum.y = 0;
rotationY = -Camera.main.transform.localEulerAngles.x;
}

In the motor code I have a flag that tells when the LERPing is done as well - it then rotates the motor to the proper x/z vector, and then sets the camera so that it’s looking that same way:

//at the end of CharacterMotor.js…
if (turnToCamera == true)
{
turnToCamera = false;
transform.rotation = newLookQuat;//the Qauternion at the end of the Camera lerp…
Camera.main.transform.LookAt(Camera.main.transform.position + Vector3(0,0,0) + (transform.forward * 10000)); //reorient
}


Extremely hacky, I know, and it was tempting to write a custom controller, but the default FPSController solved a lot of issues out the gate, and this (fingers crossed) seems to work - I’ll have to do a few more tests, and the other folks on the team are good at breaking things made of duct-taped code :slight_smile: