Confiner & Impulse Listener don't play nice together?

Currently my game makes extensive use of the Cinemachine Confiner (with some custom adjustments for perspective mode). I’m noticing though that when I use it along with a cinemachine impulse source / listener I believe the confiner messes with the impulse as I believe the confiner is trying to adjust the camera bounds back to normal while the impulse is occurring.

I’m wondering if what i’m seeing makes some sense or if i’m maybe just going a little crazy from staring at camera shakes for too long haha.

Thanks in advance!

Can you show an example of what you are seeing?

Hello,

I’m wondering if I can chime in this thread with an issue I’m experiencing that may be related. I’m working on a 2D game using an orthographic camera, using a vcam with a confiner with 0 damping. I was looking to do some very simple camera shake and used the CinemachineBasicMultiChannelPerlin 2DCameraShake noise profile to accomplish this. It worked well, however with the recent update to v2.6.0 of Cinemachine, it looks like the confiner now overrides the perlin noise, and confines the shake when the camera hits the confiner edge. To verify this behaviour, I tested on v2.5.0 and the camera shake works again.

I figured maybe I should use impulse instead, so I set it up and got similar behaviour (although I admittedly may have set it up incorrectly since it’s a bit more complicated to use).

I understand if this is intended behaviour, but I’m wondering if there is a way to get camera shaking to work with confiners. One way “around” it was to allow the confiner to dampen a little whenever a camera shake was active, but it produced an undesired result if the shake occurred while the camera was also moving (for ex. moving left/right during the camera shake would make the camera shift left/right a lot, resulting in a bad looking camera shake).

Thanks for the help,

Kenny

@CDGKen Thanks for that description. It sounds like a script execution order issue. Script execution order is undefined or scripts in the “default” category, and most of the CM extensions fall into that category. Can you try setting the execution order for CinemachineConfiner to be earlier than default? The info is stored in the metafile of the script which is part of the CM package, so you will have to modify the package to test this out.

Thanks for helping look into this.

Unfortunately changing the script execution order of Cinemachine.CinemachineConfiner does not seem to change anything. (I changed the order via the meta file in the package folder as you suggested since adding it via Script Execution Order in the Project Settings would not make the change stick).

I changed it to just before default, and well before default, but had the same result. In a hail mary attempt I tried moving the confiner script above the virtual camera script on the component but that didn’t work either.

I had a look at the code and it turns out that yes there was a change in 2.6.0 that produces this result, and changing the execution order won’t help. We’ll look into correcting this for 2.6.1.

Thanks for looking into it.

I’m sorry for asking this, but assuming it’s not a big code change, would it be possible to get a suggested fix I could apply on the Cinemachine package on my end? We’re planning on launching our game in two weeks, and it would be great if we could have a fix for this, however unofficial it is.

The PR is here, but it hasn’t yet been reviewed:
https://github.com/Unity-Technologies/upm-package-cinemachine/pull/88

We’re fast-tracking this for the upcoming 2.6.1 release. You might want to wait until the end of the week, when a preview is likely to be available.

Oh wow, that’s terrific. I’ll keep my eye out for the preview. Thanks so much!

@CDGKen CM 2.6.1-preview.6 is now available

We’ve updated, and it looks like the previous behaviour is working again! Thanks for keeping track of this and letting me know.

2 Likes

Hi, I’m having the same issue even though I updated the package >= 2.6.1.
Tested 2.5.0, 2.6.1, 2.6.3 and only 2.5.0 works…

Can you make a small repro project that shows this problem with 2.6.3?

Here you are

6375408–709821–ConfinedImpulse.zip (88.3 KB)

Thanks for the upload. When I run it, I see that the impulse is being correctly confined by the confiner: it is behaving as expected. What behaviour are you expecting to see?

Confiner no longer confines noise and impulse

I want to have my vcam shake when it detects an impulse, regardless of whether or not it’s confined.
The way I see it, that’s what’s expected… isn’t it?

oh right, I got mixed up. Sorry!

So yes, the confiner confines the impulses. It always behaved this way; the regression was about Perlin Noise. However, you are right, there should be a way to decide whether you want impulses to be confined or not.

We will add an option to Impulse Listener that allows you to make that choice. In the meantime, it is very easy to make a custom extension that does what you want. Here it is, just drop it in your assets and use it instead of Impulse Listener. It will appear automatically in the vcam Extensions dropdown.

using UnityEngine;
namespace Cinemachine
{
    /// <summary>
    /// An extension for Cinemachine Virtual Camera which post-processes
    /// the final position of the virtual camera.  It listens for CinemachineImpulse
    /// signals on the specified channels, and moves the camera in response to them.
    /// </summary>
    [SaveDuringPlay]
    [AddComponentMenu("")] // Hide in menu
    [ExecuteAlways]
    public class CinemachineLateImpulseListener : CinemachineExtension
    {
        /// <summary>
        /// Impulse events on channels not included in the mask will be ignored.
        /// </summary>
        [Tooltip("Impulse events on channels not included in the mask will be ignored.")]
        [CinemachineImpulseChannelProperty]
        public int m_ChannelMask = 1;

        /// <summary>
        /// Gain to apply to the Impulse signal.
        /// </summary>
        [Tooltip("Gain to apply to the Impulse signal.  1 is normal strength.  "
            + "Setting this to 0 completely mutes the signal.")]
        public float m_Gain = 1;

        /// <summary>
        /// Enable this to perform distance calculation in 2D (ignore Z).
        /// </summary>
        [Tooltip("Enable this to perform distance calculation in 2D (ignore Z)")]
        public bool m_Use2DDistance = false;

        /// <summary>React to any detected impulses</summary>
        /// <param name="vcam">The virtual camera being processed</param>
        /// <param name="stage">The current pipeline stage</param>
        /// <param name="state">The current virtual camera state</param>
        /// <param name="deltaTime">The current applicable deltaTime</param>
        protected override void PostPipelineStageCallback(
            CinemachineVirtualCameraBase vcam,
            CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
        {
            if (stage == CinemachineCore.Stage.Noise)
            {
                Vector3 impulsePos = Vector3.zero;
                Quaternion impulseRot = Quaternion.identity;
                if (CinemachineImpulseManager.Instance.GetImpulseAt(
                    state.FinalPosition, m_Use2DDistance, m_ChannelMask,
                    out impulsePos, out impulseRot))
                {
                    state.PositionCorrection += impulsePos * -m_Gain;
                    impulseRot = Quaternion.SlerpUnclamped(Quaternion.identity, impulseRot, -m_Gain);
                    state.OrientationCorrection = state.OrientationCorrection * impulseRot;
                }
            }
        }
    }
}

Wow, I didn’t expect to get this issue solved this quick. I just applied the custom extension you posted to my working project and confirmed that it works pefectly. I appreciate your passionate support. Thanks!

1 Like

Just wanted to drop a quick note to say thanks for the above script Gregoryl! I was having the same problem and this worked like a charm!

1 Like

CM 2.7.1 has the option added to Impulse Listener