From 8de3812b77e5ac1e8e8d3e3178c1dd8de6a6f71f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Par=C3=A9-Vogt?= Date: Fri, 20 Feb 2026 16:31:53 -0500 Subject: [PATCH 1/4] Add test for UUM-131151 --- .../Tests/Runtime/CamerasBlendingTests.cs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/com.unity.cinemachine/Tests/Runtime/CamerasBlendingTests.cs b/com.unity.cinemachine/Tests/Runtime/CamerasBlendingTests.cs index 666c36882..9b2834972 100644 --- a/com.unity.cinemachine/Tests/Runtime/CamerasBlendingTests.cs +++ b/com.unity.cinemachine/Tests/Runtime/CamerasBlendingTests.cs @@ -210,5 +210,48 @@ public IEnumerator SetActiveBlend() yield return UpdateCinemachine(); Assert.That(m_Brain.ActiveBlend == null); } + + [UnityTest] + [Description("Regression test for UUM-131151 tests that blend snapshots are reset correctly when blending is interrupted")] + public IEnumerator BlendClearsSnapshotWhenBlendingIsInterrupted() + { + // We test cancelling a blend, changing the source camera position and then restarting the blend + // The camera must be in FreezeWhenBlendingOut mode + // We expect the blend to start from the new position + + ((CinemachineCamera)m_Source).BlendHint |= CinemachineCore.BlendHints.FreezeWhenBlendingOut; + + yield return UpdateCinemachine(); + Assume.That(ReferenceEquals(m_Brain.ActiveVirtualCamera, m_Source)); + Assume.That(m_Brain.transform.position, Is.EqualTo(m_Source.transform.position)); + + // Start blend to target + m_Target.enabled = true; + yield return UpdateCinemachine(); + Assume.That(m_Brain.IsBlending, Is.True); + + yield return UpdateCinemachine(); + + // Cancel, blend back to source + m_Target.enabled = false; + yield return UpdateCinemachine(); + Assume.That(m_Brain.IsBlending, Is.True); + + while (m_Brain.IsBlending) + yield return UpdateCinemachine(); + + Assume.That(ReferenceEquals(m_Brain.ActiveVirtualCamera, m_Source)); + Assume.That(m_Brain.transform.position, Is.EqualTo(m_Source.transform.position)); + + var newPos = new Vector3(0, 5, 0); + m_Source.transform.position = newPos; + + // Restart blend to target + m_Target.enabled = true; + yield return UpdateCinemachine(); + + // Make sure we started from 0, 5, 0 and not 10, 0, 0 + Assert.That(m_Brain.transform.position.y, Is.GreaterThan(4.0f)); + } } } \ No newline at end of file From 3ef36a1c892b733852bbe66d2257150673807fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Par=C3=A9-Vogt?= Date: Fri, 20 Feb 2026 16:43:55 -0500 Subject: [PATCH 2/4] Fix for UUM-131151 --- .../Runtime/Core/CameraBlendStack.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs b/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs index a6431f861..1deb21633 100644 --- a/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs +++ b/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs @@ -101,6 +101,13 @@ public ICinemachineCamera GetSnapshotIfAppropriate(ICinemachineCamera cam, float // Use the most recent snapshot return m_Snapshot; } + + public void ClearSnapshot() + { + m_Snapshot.TakeSnapshot(null); + m_SnapshotSource = null; + m_SnapshotBlendWeight = 0; + } } // Current game state is always frame 0, overrides are subsequent frames @@ -213,6 +220,7 @@ public void ResetRootFrame() frame.Blend.CamB = null; frame.Source.ClearBlend(); frame.Source.CamB = null; + frame.ClearSnapshot(); } } @@ -329,7 +337,10 @@ public void UpdateRootFrame( // Advance the working blend if (AdvanceBlend(frame.Blend, deltaTime)) + { frame.Source.ClearBlend(); + frame.ClearSnapshot(); + } frame.UpdateCameraState(up, deltaTime); // local function From 078d5e651a844af2da4594cbf26872cd6b02322f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Par=C3=A9-Vogt?= Date: Mon, 23 Feb 2026 09:51:04 -0500 Subject: [PATCH 3/4] Add changelog entry for UUM-131151 --- com.unity.cinemachine/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/com.unity.cinemachine/CHANGELOG.md b/com.unity.cinemachine/CHANGELOG.md index c5ffcfc6f..984144ab2 100644 --- a/com.unity.cinemachine/CHANGELOG.md +++ b/com.unity.cinemachine/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [3.1.7] - 2026-02-25 +### Unreleased + +### Bugfixes +- Fixed stack frame snapshot not resetting when CameraBlendStack completed blend. + ## [3.1.6] - 2026-02-23 ### Bugfixes From df8a7662b95b16760f0d7054b89fd58a3474a00d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Par=C3=A9-Vogt?= Date: Fri, 27 Feb 2026 16:43:22 -0500 Subject: [PATCH 4/4] Fix pr comment --- com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs b/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs index 1deb21633..9fa7c3b53 100644 --- a/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs +++ b/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs @@ -83,10 +83,8 @@ public ICinemachineCamera GetSnapshotIfAppropriate(ICinemachineCamera cam, float { if (cam == null || (cam.State.BlendHint & CameraState.BlendHints.FreezeWhenBlendingOut) == 0) { - // No snapshot required - reset it - m_Snapshot.TakeSnapshot(null); - m_SnapshotSource = null; - m_SnapshotBlendWeight = 0; + // No snapshot required - clear it + ClearSnapshot(); return cam; } // A snapshot is needed