Cinemachine Collider Stuttering

What should I do to fix the stuttering that happens when the camera collides with the terrain?

It’s not clear why you have that stuttering. Can you please post:

  • an image of your vcam inspector
  • and image of your CM Brain inspector
  • what version of CM and Unity you are using

I’m using Cinemachine 2.3.4 with Unity 2019.1.0f2
Here are the images:

Hmmm… everything looks fine and dandy.
It’s not immediately obvious why you’re getting the stuttering.
Would you be willing to export a unitypackage containing a simple and lightweight reproduction of this problem, and send it to me?

Sure! Here:

4711736–445289–testpkg.unitypackage (1.91 MB)

Thanks for packaging that up!

Well, I think your use case pushes the collider way beyond its intended purpose. There aren’t any settings that will get rid of the artifacts, unfortunately.

We’ll have to come up with a new strategy. Can you describe qualitatively how you’d like the camera to behave? For example: “as if a cameraman is walking along behind the character. When the character is obstructed by a hill, I’d like the camera to do X”.

If you just want a camera that follows the terrain at a fixed height from the surface, then the solution is quite simple: replace the CinemachineCollider with an extension that hugs the camera to the terrain. Here is an example of one:

using UnityEngine;
using Cinemachine;

[AddComponentMenu("")] // Hide in menu
[SaveDuringPlay]
#if UNITY_2018_3_OR_NEWER
[ExecuteAlways]
#else
[ExecuteInEditMode]
#endif
public class CinemachineTerrainHugger : CinemachineExtension
{
    public TerrainCollider m_Terrain;
    public float m_CameraHeight = 1;

    private void OnValidate()
    {
        m_CameraHeight = Mathf.Max(0, m_CameraHeight);
    }

    protected override void PostPipelineStageCallback(
        CinemachineVirtualCameraBase vcam,
        CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
    {
        if (stage == CinemachineCore.Stage.Body && m_Terrain != null)
        {
            var b = m_Terrain.bounds;
            var camPos = state.CorrectedPosition;
            camPos.y = b.max.y + 1;
            if (m_Terrain.Raycast(new Ray(camPos, Vector3.down), out RaycastHit hit, b.max.y - b.min.y + 2))
            {
                camPos = hit.point;
                camPos.y += m_CameraHeight;
                state.PositionCorrection += camPos - state.CorrectedPosition;
            }
        }
    }
}

Sorry for the (very) late reply, been kind of busy with other projects. Will test it as soon as I can! Thanks for the help!

No worries! Let me know how it goes.