XaiJu
Megan Fox
Megan Fox

patreon


Cinemachine For 3rd Person Action/Vehicle

First, check out the Patron page, 'cus I updated a bunch of stuff! Everyone still gets the same rewards they pledged at, I just cleaned up the explanations, and changed the goals. Now the goals are more like "things you guys get when we reach milestones" instead of "uh, thanks? yay!". When we hit the vote goal hopefully soon, you'll start seeing additional vote links in here n stuff.

Second - wanna know how this all looks in practice? Go here. Want some already set-up cameras to work with, so you can start with decent-feeling defaults? Go here.

Ok, then, so - cameras! Sorry for the delay. It was because I was fighting with bugs in Cinemachine (more on that later).

Everything I'm going to share here is in the context of skate games, cus, obviously. As such, I'm gonna use some terms like "vert" - which means when you roll the skateboard up a huge ramp to the part where you're basically riding up a vertical wall. However, the camera I propose is pretty much exactly what you'd want for a 3rd-person action or racing vehicle game too. Stuff like... I don't know, Grand Theft Auto - you need a smooth camera that follows you around as you drive, you need it to snap behind and look forward when you're aiming, and you probably need it to do different stuff when climbing ladders or such, right? Same basic challenges I'm facing.

Now then...

Trick #1: Don't target the player directly

It's tempting to point the camera directly at the player object and walk away, but, don't, trust me. You get into a car? Ok you probably aren't wanting to look at the body incidentally in the driver's seat anymore. You climb a ladder? Ok are we looking at the middle of the ladder (not helpful), or are we maybe looking at the top of the ladder where you're gonna finish the climb and pop out in front of a dude pointing a gun at you. Ok you died and exploded into bits... uh... which bit is the player?

You get the idea. You want to point the camera at something separate from the player, but that follows the player. The way I achieve this is with a Camera Follow object that I just child in under my player prefab.

In Awake(), it stores its parent (something like "myParent = transform.parent", nothing fancy) then does transform.parent = null to pop off. After that, it just moves itself to match the position and rotation of whatever its parent used to be.

I use this kind of logic for a lot of stuff, like say, skate wheels. My prefab has 4 separate rigid body skate wheels in it, which are jointed to the parent rigid body, but Unity can get weird if you run rigid bodies as children of other rigid bodies with joints. So during Awake(), they pop themselves off. All kinds of stuff works better if you pop it off, and it saves you from having 3 billion separate prefabs you need to remember the purposes of.

Anywho, moving on...

Trick #2: Don't Move The Camera Yourself, Use The State-Based Blend System

My first go at this had me waiting until I was in vert, and then reaching in and changing the camera offset to be higher, and then it would snap the camera around behind you when you stopped and were spinning in place, and wow did it feel awful. It breaks Cinemachine, hard pops for days.

You want a setup more like this:

See how the Main Camera isn't actually childed to anything, and it's totally separate? That's the thing actually rendering the world. The Cinemachine Brain is being controlled by the State Driven Camera, and the post-processing on there is being controlled by the Cinemachine Post Processing. Which, by the way, you probably want on the parent State Driven Camera object, rather than on the child cameras. You can absolutely put it on the child cameras if you want different post processing per camera, but, you'll find that when it blends between cameras, it may behave oddly - like the vignette may blend out then back, or your depth of field might pop, or the like.

See the animator on the skate brain? That's what actually controls the camera that's currently active. Chase Cam is is the smooth chase cam when you're skating around, Snap Behind is the one where you need to be looking hard-forward when you're stopped and turning in place, Orbit Cam is when you move the right stick to look around, and Vert is the camera it kicks to when you're rolling up a ramp near the top (and fly off the top and do an air trick and then come back down into the ramp).

There isn't actually a mesh or any actual animations involved. It's literally just an animation controller. It looks like this. All the nodes look this way, only the names are different.

So when I want to snap the camera behind, I don't reach in and wrangle positions directly. I just set the animator's "Snapped" bool to true, and it enters the state, and then the Cinemachine State Driven Camera makes that blend look butter smooth. If you try and do the blend manually, you'll find it's much harder to make it smooth.

Trick #3: You May Need To Do Some Camera Tweaking

Each of my cameras does still have a script, and they do occasionally tweak things. They're derived off "CinemachineExtension", and the main function in them is an overload of "protected override void PostPipelineStageCallback(CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime)". Code tier, just look at the code tier, everyone else, you'll find if you google you can find some example code for how it looks.

The gist is, you're interjecting logic into various stages of the main camera brain's processing. Mostly, I use them for interjecting player control. Like in the Orbit and the Vert camera, for applying the player's control, I'm manually adjusting m_FollowOffset on the transposer during the Body phase. You could just rely on it it doing that for you, since you can specify the input binding for it, but then that won't work for you if your inputs are rebindable, etc etc. Point is, you can fiddle in there, but you'll probably keep it use-case specific and minimal.

Trick #4: You Can Smooth Your LookAt Point

Remember how we kept a separate look-at point? Well hot dang, that means we can cover for a LOT of weird stuff our player object might do. Like we could put a RigidBody on there (which we set to collide with nothing probably), and set the RigidBody to be Interpolated, and then we could move the camera during FixedUpdate via MovePosition/MoveRotation. Tada! Now your camera interpolates in super smooth fashion, basically for free. Neat, eh?

Trick #5: Actually This Is A Warning

There is, however, a hurdle. At least on the Cinemachine version I'm using (2.1.10), I'm getting this horrible jitter that is entirely related to the camera, when the FPS drops below about 40. Great until then, unusable after. This, I gather, is because my character is physics-driven, and thus has an imperceptible to the naked eye jitter. If I use a stationary cam, the character looks butter smooth at all FPS, and if I hard-weld a camera to the board, it's butter smooth at all FPS, but if I make Cinemachine look at it, jitter-central.

This, I gather, MAY have since been fixed, for all you lucky people on 2018, though. 2018.3 especially, the latest version, has fixes specifically related to following a rigid body better. Remember that tip about turning your look-at object into an interpolated rigid body? Bingo.

So! This is where I leave you. Feel free to ask questions, but hopefully this will save you a ton of time, and get you up and running with a pretty nice-feeling camera with minimal effort. The big thing that kept stumbling me was not getting how important letting Cinemachine handle blending itself was. Even if you don't want to use the State Based Camera, Cinemachine has other camera-blending methods you can use (which you'll want to look at if you're focusing more on cutscene-driven cameras).

The key is just, use them. Don't reach in and try to manually change the values to make the camera do what you want. Instead, make a whole bunch of separate cameras that you've tweaked (via the Inspector) to behave like you want in the specific situation, then figure out a way of telling Cinemachine to blend to that camera in that situation.

Code tier and above patrons? You'll be watching to go here next, presumably.


More Creators