diff --git a/com.unity.cinemachine/CHANGELOG.md b/com.unity.cinemachine/CHANGELOG.md index 8778e0952..b68127128 100644 --- a/com.unity.cinemachine/CHANGELOG.md +++ b/com.unity.cinemachine/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Decollider would sometimes cause camera to slip inside cracks between adjacent colliders. - The Deoccluder failed to reset its state when initially enabled, and sometimes caused small spurious camera rotations. - Fixed the Radial Axis input axis in the CinemachineOrbitalFollow component to map to the y axis. +- Desired blend time is respected when interrupting blends with heterogeneous blend-in and blend-out times. ### Changed - Added delayed processing to near and far clip plane inspector fields for the CinemachineCamera lens. diff --git a/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs b/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs index 73a2ec59e..183d126e9 100644 --- a/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs +++ b/com.unity.cinemachine/Runtime/Core/CameraBlendStack.cs @@ -234,6 +234,7 @@ public void UpdateRootFrame( if (activeCamera != outgoingCamera) { bool backingOutOfBlend = false; + float backingOutPercentCompleted = 0; float duration = 0; // Do we need to create a game-play blend? @@ -246,6 +247,8 @@ public void UpdateRootFrame( { // Are we backing out of a blend-in-progress? backingOutOfBlend = frame.Source.CamA == activeCamera && frame.Source.CamB == outgoingCamera; + if (backingOutOfBlend && frame.Blend.Duration > kEpsilon) + backingOutPercentCompleted = frame.Blend.TimeInBlend / frame.Blend.Duration; frame.Source.CamA = outgoingCamera; frame.Source.BlendCurve = blendDef.BlendCurve; @@ -289,11 +292,15 @@ public void UpdateRootFrame( if (backingOutOfBlend) { snapshot = true; // always use a snapshot for this to prevent pops - duration = frame.Blend.TimeInBlend; + var adjustedDuration = frame.Blend.TimeInBlend; if (nbs != null) - duration += nbs.Blend.Duration - nbs.Blend.TimeInBlend; + adjustedDuration += nbs.Blend.Duration - nbs.Blend.TimeInBlend; else if (frame.Blend.CamA is SnapshotBlendSource sbs) - duration += sbs.RemainingTimeInBlend; + adjustedDuration += sbs.RemainingTimeInBlend; + + // In the event that the blend times in the different directions are different, + // don't make the blend longer than it would otherwise have been + duration = Mathf.Min(duration * backingOutPercentCompleted, adjustedDuration); } // Chain to existing blend