Stop cinemachine follow camera from rolling AND allowing the player to drive upside down

I’m building a racing game with motorbikes, the motorbikes can lean into corners, drive on walls, upside down etc.

I’m using Cinemachine 3.1.2 and I have an Orbital Follow component attached to my Cinemachine Camera and it works great - but as the vehicle physics leans into corners, so does the camera. I’m using Orbital Follow’s Lock To Target binding mode which works great even upside down. When I select Lock To Target (No Roll) I get the desired effect of the camera not rolling when turning, but when going upside down the camera is inverted.

Does Cinemachine have a setting that can have a no roll camera AND allow my motorbikes to drive upside down without flipping? Or is there a more programmatic solution?

I’ve attempted to create a child transform of the vehicle to make it follow the vehicle but make it independent of certain rotations (then set the Orbital Follow follow target to this child transform) but I keep running into gimbal lock. One of my ideas was to lock one axis using Quaternions (but that’s where my knowledge of using Quaternions ends!)

Anyone have any suggestions?

That’s the right idea. For solving gimbal lock, you can use your invisible proxy target as the World Up Override in the CinemachineBrain.

Take a look at the FreeLook on Spherical Surface sample scene for a good example of this sort of thing.

Hi Gregoryl,

Thanks for the suggestion, I used the code from the example in my prototype and while the world up alignment worked, the camera still rolls with the bike. I noticed in the Spherical Surface sample scene if you rotate the character on the z axis, the camera locks and rotates with the character, and not perpendicular from the sphere.

Is there such a thing in Cinemachine to add the inverse rotation to the ‘invisible proxy target’ to counter the motorbike roll into corners? (While still being correctly orientated when upside down?)

Your invisible target proxy will effectively control the camera rotation, so it should be filtering out the bike’s roll. I thought that’s what you were doing when you said “create a child transform of the vehicle to make it follow the vehicle but make it independent of certain rotations”. Or am I misunderstanding something?

That’s right…or at least the intention!

I can either get the roll to stop, or the camera inverts correctly when upside down, not both at the same time.

I’m using this code to invert the roll in conjunction with the setup from the Spherical Surface sample scene, ‘target’ is the motorbike:

float rotZ = target.rotation.z;
transform.SetPositionAndRotation(target.position, Quaternion.AngleAxis(-rotZ, target.forward));

I don’t have enough context to comment on that code.

What if you always oriented the local up of the proxy target to be same as the normal of the surface the bike is on? With damping of course for smoothness.

That was one of the ideas I tried - but the track isn’t always smooth, there are off road sections with angled faces and kerbs and ledges and other geometry. I’ll have a play around, quaternions aren’t my strong suit - my priority is having the camera orientate correctly upside down, I want to make sure players can see where they’re going!

Thanks for your help! :slight_smile:

Yes, the problem is a little tricky. Your code needs some way to figure out which way is up. From what you describe, that needs to be done based on the surface the bike is currently riding on. If it’s bumpy, you might be able to get away with some highly damped calculation that will effectively smooth over the bumps. Basically find the current normal of the surface you’re on, and gradually move your local up towards it.

Another option could be to make a smooth mesh under the track, on a different layer, and have your normal-seeking raycasts look for that.

Take a look at DampedTracker.cs in the CM samples for quaternion code that tracks a target up direction.

1 Like

Creating a smooth mesh as a camera orientation layer sounds like a great idea!

I’ve since tightened up the physics to reduce lean in and it feels much less nauseating now, you feel like you have more turn in control too and the camera doesn’t lean so much - so much so that I think I might be able to get away with it now! If I come up with some code for normal orientation I’ll post it.

Thanks for your assistance, it is much appreciated! :slight_smile: