Apply transposer damping to custom cinemachine extension.

Hi!

I have a camera setup like this:

9354422--1308509--upload_2023-9-22_11-18-18.png

And I have a custom extension to detect slope and modify the position of the camera depending on the angle of the slope (here is the UpdateCameraState function):

/// <summary>
/// Process Rotation and Translation offset for the camera
/// </summary>
protected override void UpdateCameraState(CinemachineVirtualCameraBase vcam, ref CameraState state, float deltaTime)
{
    Vector3 deltaPositionToApplyToCamera = "lots of complicated raycast and angle computation";
    state.PositionCorrection += deltaPositionToApplyToCamera;
}

The extension is due to apply in the Body stage as it changes the position of the camera but not its orientation. I have no other active cinemachine extension.

9354422--1308512--upload_2023-9-22_11-21-34.png

Everything is working fine BUT the damping that I have setup in the cinemachine virtual camera is not applied to the change in position I make in the slopePrediction extension.

Is there something to do about it? Is my configuration wrong somehow?

Thanks for the answer!

PositionCorrection is always applied without any damping. You have to implement your own damping if you want the correction to be damped.

Thank you very much for the answer. That’s what I thought. But how would the damping from the cincemachine transposer “blend” or mix with my own damping?

What is exactly the sequence of processing in cinemachine when using extensions?

1- compute cinemachine camera position
2- compute the damping and set its value in the CameraState rawPosition?
3- compute extension camera position?

Am I correct?

Is there a way to compute the “RawPositionBeforeCinemachineDamping” in extension and let cinemachine ahandle all the damping?

Or should I just not use the damping from the cinemachine transposer and implement an extension that makes all my damping?

Transposer computes its camera position (which includes its damping) during Body stage and puts it in state.RawPosition. Internally, Transposer keeps its own state so that it can handle its damping. Your extension cannot interfere with the Transposer’s internal state, so the Transposer does not care what your extension does. This is by design.

Extensions are then called and are free to modify state.RawPosition, or to add a correction to state.PositionCorrection. Final camera position will be state.RawPosition + state.PositionCorrection. Your extension can keep its own internal state so that changes to the desired correction value can be damped using your own damping algorithm.

CinemachineConfiner.cs might be a good example here. Open it and see how it uses the m_Damping member. You can imitate it. Note the usage of VcamExtraState. This stores per-vcam state for the extension. It’s done this way rather than with simple member variables in order to allow an extension instance to be used on a manager-style camera (e.g. StateDriven or ClearShot) and thus shared among several vcams.

Thank you very much for the detailed explanation.

I just fear that having damping at several places isn’t ideal to really control how the damping applies to the position.

I will nevertheless implement my own damping extension (or add damping in the SlopeExtension one depending on the data I need) and see if I keep the default transposer damping or if I disable it.

Generally, additive damping works well. Each component contributes its own influence, with its own damping. We have not seen problems with this approach.