Skip to content

Fix for UUM-131870#1099

Open
arnaudparevogt-unity wants to merge 3 commits intomainfrom
uum-131870
Open

Fix for UUM-131870#1099
arnaudparevogt-unity wants to merge 3 commits intomainfrom
uum-131870

Conversation

@arnaudparevogt-unity
Copy link

Purpose of this PR

For for https://jira.unity3d.com/browse/UUM-131870 (https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-131870)

Issue was OnForceCameraPosition that was updated in fd5aafd to fix a bug in the portals scene (proper camera rotation when forcing camera position/rotation). The fix changed how the target position was computed, preventing OnForceCameraPosition from looking away from the target.

Now OnForceCameraPosition has proper rotation support (though m_PreviousOffset) but recomputes the new PreviousTargetPosition without going though the actual target position, allowing to force the camera to look away from the target.

Testing status

  • Added an automated test (see FollowForcePositionTests)
  • Passed all automated tests
  • Manually tested (tested portals sample)

Documentation status

  • Updated CHANGELOG
  • Updated README (if applicable)
  • Commented all public classes, properties, and methods
  • Updated user documentation

Technical risk

low risk low halo

Comments to reviewers

Broken in fd5aafd

Package version

  • Updated package version

Core issue was a bugfix for the portals scene
(fd5aafd) to account for camera
rotation when warping both a target and camera.

The bugfix erroneously changed the OnForceCameraPosition function to
rely on the target position (current transform) instead of the camera
position. This meant that forcing the camera to look away from the
target did not work.

This fix corrects the original bugfix by reverting
PreviousTargetPosition calculation method, but keeps the
m_PreviousOffset calculation method from the bugfix, as this one is
needed to account for rotations.
@cla-assistant-unity
Copy link

cla-assistant-unity bot commented Feb 13, 2026

CLA assistant check
All committers have signed the CLA.

@u-pr
Copy link
Contributor

u-pr bot commented Feb 13, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis ✅

UUM-131870 - Fully compliant

Compliant requirements:

  • The PR updates TargetTracking.OnForceCameraPosition to correctly recalculate PreviousTargetPosition based on the new camera state, ensuring the forced position is applied and maintained.
  • A new automated test LookAwayFromTarget confirms that ForceCameraPosition correctly updates the camera state to the forced values.
⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪

The PR is a focused fix in the tracking logic with a corresponding test. The code changes are minimal but require understanding of the damping math.
🏅 Score: 95

The PR provides a clean and logically sound fix for the reported regression, cleans up unused code (`m_PreviousTargetPositionDampingOffset`), and includes a specific unit test to prevent regression.
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Typo in comment

There is a typo in the comment: "posistion" should be "position".

// of snapping the camera to camera position since the camera posistion will be computed from the target and
  • Update review

🤖 Helpful? Please react with 👍/👎 | Questions❓Please reach out in Slack #ask-u-pr

@u-pr
Copy link
Contributor

u-pr bot commented Feb 13, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Reset global state after test execution

The test modifies the static property CinemachineCore.UniformDeltaTimeOverride
without resetting it, which causes side effects that can persist and affect other
tests in the suite. Wrap the test logic in a try-finally block to ensure the
original value is restored regardless of the test outcome.

com.unity.cinemachine/Tests/Runtime/FollowForcePositionTests.cs [24-44]

 [UnityTest, Description("UUM-131870: ForceCameraPosition should allow looking away from the target.")]
 public IEnumerator LookAwayFromTarget()
 {
+    var originalDeltaTime = CinemachineCore.UniformDeltaTimeOverride;
     CinemachineCore.UniformDeltaTimeOverride = 0.0f; // we only test force position, not damping
-    var follow = m_Vcam.gameObject.AddComponent<CinemachineFollow>();
-    follow.FollowOffset = new Vector3(0, 0, -10);
-    m_Vcam.Follow = m_FollowObject.transform;
+    try
+    {
+        var follow = m_Vcam.gameObject.AddComponent<CinemachineFollow>();
+        follow.FollowOffset = new Vector3(0, 0, -10);
+        m_Vcam.Follow = m_FollowObject.transform;
 
-    // Initial update to settle camera
-    m_FollowObject.transform.position = Vector3.zero;
-    yield return null;
-    Assume.That(m_Vcam.State.GetFinalPosition(), Is.EqualTo(follow.FollowOffset).Using(m_Vector3EqualityComparer));
+        // Initial update to settle camera
+        m_FollowObject.transform.position = Vector3.zero;
+        yield return null;
+        Assume.That(m_Vcam.State.GetFinalPosition(), Is.EqualTo(follow.FollowOffset).Using(m_Vector3EqualityComparer));
 
-    // Move camera away from target
-    var forcedPos = new Vector3(0, 5, -5);
-    var forcedRot = Quaternion.identity;
-    m_Vcam.ForceCameraPosition(forcedPos, forcedRot);
-    yield return null;
-    Assert.That(m_Vcam.State.GetFinalPosition(), Is.EqualTo(forcedPos).Using(m_Vector3EqualityComparer));
-    Assert.That(m_Vcam.State.GetFinalOrientation(), Is.EqualTo(forcedRot).Using(m_QuaternionComparer));
+        // Move camera away from target
+        var forcedPos = new Vector3(0, 5, -5);
+        var forcedRot = Quaternion.identity;
+        m_Vcam.ForceCameraPosition(forcedPos, forcedRot);
+        yield return null;
+        Assert.That(m_Vcam.State.GetFinalPosition(), Is.EqualTo(forcedPos).Using(m_Vector3EqualityComparer));
+        Assert.That(m_Vcam.State.GetFinalOrientation(), Is.EqualTo(forcedRot).Using(m_QuaternionComparer));
+    }
+    finally
+    {
+        CinemachineCore.UniformDeltaTimeOverride = originalDeltaTime;
+    }
 }
Suggestion importance[1-10]: 8

__

Why: The test modifies the static global property CinemachineCore.UniformDeltaTimeOverride but fails to reset it. This can cause side effects in subsequent tests within the suite, leading to potential flakiness or failures. Using a try-finally block ensures the state is restored.

Medium
  • More suggestions

🤖 Helpful? Please react with 👍/👎 | Questions❓Please reach out in Slack #ask-u-pr

@codecov-github-com
Copy link

codecov-github-com bot commented Feb 13, 2026

Codecov Report

All modified and coverable lines are covered by tests ✅

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1099   +/-   ##
=======================================
  Coverage        ?   17.36%           
=======================================
  Files           ?      209           
  Lines           ?    23697           
  Branches        ?        0           
=======================================
  Hits            ?     4115           
  Misses          ?    19582           
  Partials        ?        0           
Flag Coverage Δ
cinemachine_Windows_2022.3 17.41% <100.00%> (?)
cinemachine_Windows_6000.0 17.30% <100.00%> (?)
cinemachine_Windows_6000.2 17.30% <100.00%> (?)
cinemachine_Windows_6000.3 17.30% <100.00%> (?)
cinemachine_Windows_6000.4 17.30% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...m.unity.cinemachine/Runtime/Core/TargetTracking.cs 78.26% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant