From 18082a5694e7562b1ee8a76527364f35b2c3177a Mon Sep 17 00:00:00 2001 From: Gregory Labute Date: Sat, 25 Nov 2023 13:00:57 -0500 Subject: [PATCH] CMCL-0000: fix upgrader and legacy streaming bugs found in the Enemies demo project. (#911) * initial wip * Regression fix: Legacy Lens settings had lost their ability to be animated * Various bugs in upgrader * Update CHANGELOG.md * add missing API doc * API doc again * Fix broken legacy streaming * CmCamera inspector tweaks * more broken Legacy Upgrade --- com.unity.cinemachine/CHANGELOG.md | 4 +- .../Editor/Editors/CinemachineCameraEditor.cs | 4 +- .../Obsolete/CinemachineFreeLookEditor.cs | 10 +- .../CinemachineVirtualCameraEditor.cs | 12 +- .../LensSettingsPropertyDrawer.cs | 206 ----------- .../Upgrader/CinemachineUpgradeManager.cs | 324 +++++++++++------- .../Upgrader/UpgradeObjectToCm3.Data.cs | 29 ++ .../Editor/Upgrader/UpgradeObjectToCm3.cs | 30 +- .../Behaviours/CinemachineClearShot.cs | 25 +- .../Behaviours/CinemachineSequencerCamera.cs | 25 +- .../CinemachineStateDrivenCamera.cs | 25 +- .../Core/CinemachineVirtualCameraBase.cs | 15 +- .../Runtime/Deprecated/CinemachineFreeLook.cs | 18 +- .../Deprecated/CinemachineVirtualCamera.cs | 18 +- .../Runtime/Deprecated/LegacyLensSettings.cs | 87 ++++- .../Tests/Runtime/ClearShotTests.cs | 12 +- 16 files changed, 416 insertions(+), 428 deletions(-) diff --git a/com.unity.cinemachine/CHANGELOG.md b/com.unity.cinemachine/CHANGELOG.md index 0ce47c39a..514657ce1 100644 --- a/com.unity.cinemachine/CHANGELOG.md +++ b/com.unity.cinemachine/CHANGELOG.md @@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - Bugfix: Divide-by-zero error in InputAxis.CancelDeltaTime if deltaTime is zero. - Regression fix: CinemachineCamera inspector Solo functionality was not updating correctly. -- +- Regression fix: Legacy Lens settings had lost their ability to be animated. +- Bugfix: Upgrader was not correctly upgrading animation bindings in some cases. + ### Added - Added CinemachineVirtualCameraBase.CancelDamping() convenience method to snap camera to its target position. - Added CinemachineOrbitalFollow.TargetOffset to reposition orbit center. diff --git a/com.unity.cinemachine/Editor/Editors/CinemachineCameraEditor.cs b/com.unity.cinemachine/Editor/Editors/CinemachineCameraEditor.cs index dc3ddf4c7..fc93bf83b 100644 --- a/com.unity.cinemachine/Editor/Editors/CinemachineCameraEditor.cs +++ b/com.unity.cinemachine/Editor/Editors/CinemachineCameraEditor.cs @@ -53,17 +53,17 @@ public override VisualElement CreateInspectorGUI() this.AddCameraStatus(ux); this.AddTransitionsSection(ux, new () { serializedObject.FindProperty(() => Target.BlendHint) }); ux.Add(new PropertyField(serializedObject.FindProperty(() => Target.Lens))); - ux.Add(new PropertyField(serializedObject.FindProperty(() => Target.Target))); ux.AddHeader("Global Settings"); this.AddGlobalControls(ux); var defaultTargetLabel = new Label() { style = { alignSelf = Align.FlexEnd, opacity = 0.5f }}; - var row = ux.AddChild(new InspectorUtility.LabeledRow("Set Procedural Components", "", defaultTargetLabel)); + var row = ux.AddChild(new InspectorUtility.LabeledRow("Procedural Components", "", defaultTargetLabel)); row.focusable = false; row.style.paddingTop = InspectorUtility.SingleLineHeight / 2; row.style.paddingBottom = EditorGUIUtility.standardVerticalSpacing; + ux.Add(new PropertyField(serializedObject.FindProperty(() => Target.Target))); this.AddPipelineDropdowns(ux); ux.AddSpace(); diff --git a/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs b/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs index 19a0893db..aab7871f6 100644 --- a/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs +++ b/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs @@ -22,7 +22,7 @@ protected override void GetExcludedPropertiesInInspector(List excluded) base.GetExcludedPropertiesInInspector(excluded); excluded.Add(FieldPath(x => x.m_Orbits)); if (!Target.m_CommonLens) - excluded.Add(FieldPath(x => x.Lens)); + excluded.Add(FieldPath(x => x.m_Lens)); if (Target.m_BindingMode == TargetTracking.BindingMode.LazyFollow) { excluded.Add(FieldPath(x => x.m_Heading)); @@ -80,7 +80,7 @@ public override void OnInspectorGUI() DrawTargetsInInspector(serializedObject.FindProperty(() => Target.m_Follow), serializedObject.FindProperty(() => Target.m_LookAt)); DrawPropertyInInspector(serializedObject.FindProperty(() => Target.StandbyUpdate)); DrawPropertyInInspector(serializedObject.FindProperty(() => Target.m_CommonLens)); - DrawPropertyInInspector(serializedObject.FindProperty(() => Target.Lens)); + DrawPropertyInInspector(serializedObject.FindProperty(() => Target.m_Lens)); DrawRemainingPropertiesInInspector(); // Orbits @@ -135,13 +135,13 @@ void OnSceneGUI() if (freelook.m_CommonLens && CinemachineSceneToolUtility.IsToolActive(typeof(FoVTool))) { CinemachineSceneToolHelpers.FovToolHandle(freelook, - new SerializedObject(freelook).FindProperty(() => freelook.Lens), - freelook.Lens, IsHorizontalFOVUsed()); + new SerializedObject(freelook).FindProperty(() => freelook.m_Lens), + freelook.m_Lens.ToLensSettings(), IsHorizontalFOVUsed()); } else if (freelook.m_CommonLens && CinemachineSceneToolUtility.IsToolActive(typeof(FarNearClipTool))) { CinemachineSceneToolHelpers.NearFarClipHandle(freelook, - new SerializedObject(freelook).FindProperty(() => freelook.Lens)); + new SerializedObject(freelook).FindProperty(() => freelook.m_Lens)); } else if (freelook.Follow != null && CinemachineSceneToolUtility.IsToolActive(typeof(FollowOffsetTool))) { diff --git a/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs b/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs index c516c87c9..c038984e1 100644 --- a/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs +++ b/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs @@ -22,7 +22,7 @@ static void AdoptGameViewCameraSettings(MenuCommand command) var brain = CinemachineCore.FindPotentialTargetBrain(vcam); if (brain != null) { - vcam.Lens = brain.State.Lens; + vcam.m_Lens.SetFromLensSettings(brain.State.Lens); vcam.transform.SetPositionAndRotation(brain.transform.position, brain.transform.rotation); } } @@ -31,7 +31,7 @@ static void AdoptGameViewCameraSettings(MenuCommand command) static void AdoptSceneViewCameraSettings(MenuCommand command) { var vcam = command.context as CinemachineVirtualCamera; - vcam.Lens = CinemachineMenu.MatchSceneViewCamera(vcam.transform); + vcam.m_Lens.SetFromLensSettings(CinemachineMenu.MatchSceneViewCamera(vcam.transform)); } /// Get the property names to exclude in the inspector. @@ -125,13 +125,13 @@ void OnSceneGUI() if (CinemachineSceneToolUtility.IsToolActive(typeof(FoVTool))) { CinemachineSceneToolHelpers.FovToolHandle(vcam, - new SerializedObject(vcam).FindProperty(() => vcam.Lens), - vcam.Lens, IsHorizontalFOVUsed()); + new SerializedObject(vcam).FindProperty(() => vcam.m_Lens), + vcam.m_Lens.ToLensSettings(), IsHorizontalFOVUsed()); } else if (CinemachineSceneToolUtility.IsToolActive(typeof(FarNearClipTool))) { CinemachineSceneToolHelpers.NearFarClipHandle(vcam, - new SerializedObject(vcam).FindProperty(() => vcam.Lens)); + new SerializedObject(vcam).FindProperty(() => vcam.m_Lens)); } Handles.color = originalColor; } @@ -153,7 +153,7 @@ public override void OnInspectorGUI() DrawPropertyInInspector(serializedObject.FindProperty(() => Target.OutputChannel)); DrawTargetsInInspector(serializedObject.FindProperty(() => Target.m_Follow), serializedObject.FindProperty(() => Target.m_LookAt)); DrawPropertyInInspector(serializedObject.FindProperty(() => Target.StandbyUpdate)); - DrawPropertyInInspector(serializedObject.FindProperty(() => Target.Lens)); + DrawPropertyInInspector(serializedObject.FindProperty(() => Target.m_Lens)); DrawRemainingPropertiesInInspector(); m_PipelineSet.OnInspectorGUI(!IsPropertyExcluded("Header")); DrawNonExcludedExtensionsWidgetInInspector(); diff --git a/com.unity.cinemachine/Editor/PropertyDrawers/LensSettingsPropertyDrawer.cs b/com.unity.cinemachine/Editor/PropertyDrawers/LensSettingsPropertyDrawer.cs index 9b7dee16b..f4c5967d8 100644 --- a/com.unity.cinemachine/Editor/PropertyDrawers/LensSettingsPropertyDrawer.cs +++ b/com.unity.cinemachine/Editor/PropertyDrawers/LensSettingsPropertyDrawer.cs @@ -466,211 +466,5 @@ void WritePhysicalSettings(in LensSettings.PhysicalSettings s) p.FindPropertyRelative(() => s_Def.PhysicalProperties.Anamorphism).floatValue = s.Anamorphism; } } - -#if true - ///=========================================================================== - /// IMGUI IMPLEMENTATION (to be removed) - ///=========================================================================== - - static readonly GUIContent HFOVLabel = new ("Horizontal FOV", "Horizontal Field of View"); - static readonly GUIContent VFOVLabel = new ("Vertical FOV", "Vertical Field of View"); - static readonly GUIContent FocalLengthLabel = new ("Focal Length", "The length of the lens (in mm)"); - static readonly GUIContent OrthoSizeLabel = new ("Ortho Size", "When using an orthographic camera, " - + "this defines the half-height, in world coordinates, of the camera view."); - static readonly GUIContent AdvancedLabel = new ("Advanced"); - static readonly string AdvancedHelpboxMessage = "Lens Mode Override must be enabled in the Cinemachine Brain for Mode Override to take effect"; - - static bool s_AdvancedLensExpanded; - - struct Snapshot - { - public bool IsOrtho; - public bool IsPhysical; - public float Aspect; - public bool UseHorizontalFOV; - } - Snapshot m_Snapshot; - - const float vSpace= 2; - - void SnapshotCameraShadowValues(SerializedProperty property) - { - // Assume lens is up-to-date - m_Snapshot.UseHorizontalFOV = UseHorizontalFOV(property); - m_Snapshot.IsOrtho = IsOrtho(property); - m_Snapshot.IsPhysical = IsPhysical(property); - m_Snapshot.Aspect = Aspect(property); - } - - GUIContent GetFOVLabel() - { - if (m_Snapshot.IsOrtho) return OrthoSizeLabel; - if (m_Snapshot.IsPhysical) return FocalLengthLabel; - return m_Snapshot.UseHorizontalFOV ? HFOVLabel : VFOVLabel; - } - - void DrawFOVControl(Rect rect, SerializedProperty property, GUIContent label) - { - if (m_Snapshot.IsOrtho) - EditorGUI.PropertyField( - rect, property.FindPropertyRelative(() => s_Def.OrthographicSize), label); - else if (m_Snapshot.IsPhysical) - DrawFocalLengthControl(rect, property, label); - else - { - var FOVProperty = property.FindPropertyRelative(() => s_Def.FieldOfView); - float aspect = m_Snapshot.Aspect; - float f = FOVProperty.floatValue; - if (m_Snapshot.UseHorizontalFOV) - f = Camera.VerticalToHorizontalFieldOfView(f, aspect); - EditorGUI.BeginProperty(rect, label, FOVProperty); - f = EditorGUI.FloatField(rect, label, f); - if (m_Snapshot.UseHorizontalFOV) - f = Camera.HorizontalToVerticalFieldOfView(Mathf.Clamp(f, 1, 179), aspect); - if (!Mathf.Approximately(FOVProperty.floatValue, f)) - FOVProperty.floatValue = Mathf.Clamp(f, 1, 179); - EditorGUI.EndProperty(); - } - } - - void DrawFocalLengthControl(Rect rect, SerializedProperty property, GUIContent label) - { - var FOVProperty = property.FindPropertyRelative(() => s_Def.FieldOfView); - var physicalProp = property.FindPropertyRelative(() => s_Def.PhysicalProperties); - var sensorSizeProp = physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.SensorSize); - - float f = Camera.FieldOfViewToFocalLength(FOVProperty.floatValue, sensorSizeProp.vector2Value.y); - EditorGUI.BeginProperty(rect, label, FOVProperty); - f = EditorGUI.FloatField(rect, label, f); - f = Camera.FocalLengthToFieldOfView(Mathf.Max(0.01f, f), sensorSizeProp.vector2Value.y); - if (!Mathf.Approximately(FOVProperty.floatValue, f)) - FOVProperty.floatValue = Mathf.Clamp(f, 1, 179); - EditorGUI.EndProperty(); - } - - public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label) - { - rect.height = EditorGUIUtility.singleLineHeight; // draw one line at a time - - var fovLabel = GetFOVLabel(); - var fovLabelWidth = GUI.skin.label.CalcSize(fovLabel).x; - - property.isExpanded = EditorGUI.Foldout( - new Rect(rect.x, rect.y, EditorGUIUtility.labelWidth - fovLabelWidth, rect.height), - property.isExpanded, label, true); - - if (!property.isExpanded) - { - // Put the FOV on the same line - var oldIndent = EditorGUI.indentLevel; - EditorGUI.indentLevel = 0; - var oldLabelWidth = EditorGUIUtility.labelWidth; - var delta = EditorGUIUtility.labelWidth - fovLabelWidth; - EditorGUIUtility.labelWidth = fovLabelWidth; - DrawFOVControl( - new Rect(rect.x + delta, rect.y, rect.width - delta, rect.height), - property, fovLabel); - EditorGUIUtility.labelWidth = oldLabelWidth; - EditorGUI.indentLevel = oldIndent; - } - else - { - ++EditorGUI.indentLevel; - - rect.y += rect.height + vSpace; - DrawFOVControl(rect, property, fovLabel); - - rect.y += rect.height + vSpace; - var nearClip = property.FindPropertyRelative(() => s_Def.NearClipPlane); - EditorGUI.PropertyField(rect, nearClip); - if (!m_Snapshot.IsOrtho && nearClip.floatValue < 0.01f) - { - nearClip.floatValue = 0.01f; - property.serializedObject.ApplyModifiedPropertiesWithoutUndo(); - } - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, property.FindPropertyRelative(() => s_Def.FarClipPlane)); - - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, property.FindPropertyRelative(() => s_Def.Dutch)); - - if (m_Snapshot.IsPhysical) - { - var physicalProp = property.FindPropertyRelative(() => s_Def.PhysicalProperties); - rect.y += rect.height + vSpace; - physicalProp.isExpanded = EditorGUI.Foldout(rect, physicalProp.isExpanded, physicalProp.displayName, true); - if (physicalProp.isExpanded) - { - ++EditorGUI.indentLevel; - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.GateFit)); - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.SensorSize)); - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.LensShift)); - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.Iso)); - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.ShutterSpeed)); - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.Aperture)); - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.BladeCount)); - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.Curvature)); - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.BarrelClipping)); - rect.y += rect.height + vSpace; - EditorGUI.PropertyField(rect, physicalProp.FindPropertyRelative(() => s_Def.PhysicalProperties.Anamorphism)); - --EditorGUI.indentLevel; - } - } - if (!HideModeOverride) - { - rect.y += rect.height + vSpace; - s_AdvancedLensExpanded = EditorGUI.Foldout(rect, s_AdvancedLensExpanded, AdvancedLabel); - if (s_AdvancedLensExpanded) - { - ++EditorGUI.indentLevel; - rect.y += rect.height + vSpace; - var r = EditorGUI.IndentedRect(rect); r.height *= 2; - EditorGUI.HelpBox(r, AdvancedHelpboxMessage, MessageType.Info); - - rect.y += r.height + vSpace; - EditorGUI.PropertyField(rect, property.FindPropertyRelative(() => s_Def.ModeOverride)); - --EditorGUI.indentLevel; - } - } - --EditorGUI.indentLevel; - } - property.serializedObject.ApplyModifiedProperties(); - } - - public override float GetPropertyHeight(SerializedProperty property, GUIContent label) - { - SnapshotCameraShadowValues(property); - - var lineHeight = EditorGUIUtility.singleLineHeight; - if (!property.isExpanded) - return lineHeight; - - int numLines = 4; - if (m_Snapshot.IsPhysical) - { - numLines += 1; - var physicalProp = property.FindPropertyRelative(() => s_Def.PhysicalProperties); - if (physicalProp.isExpanded) - numLines += 10; - } - if (!HideModeOverride) - { - // Advanced section - numLines += 1; - if (s_AdvancedLensExpanded) - numLines += 3; // not correct but try to make it big enough to hold the help box - } - return lineHeight + numLines * (lineHeight + vSpace); - } -#endif } } diff --git a/com.unity.cinemachine/Editor/Upgrader/CinemachineUpgradeManager.cs b/com.unity.cinemachine/Editor/Upgrader/CinemachineUpgradeManager.cs index 3eea4f72d..80f04754f 100644 --- a/com.unity.cinemachine/Editor/Upgrader/CinemachineUpgradeManager.cs +++ b/com.unity.cinemachine/Editor/Upgrader/CinemachineUpgradeManager.cs @@ -1,5 +1,5 @@ #if !CINEMACHINE_NO_CM2_SUPPORT -// #define DEBUG_HELPERS +//#define DEBUG_HELPERS #pragma warning disable CS0618 // suppress obsolete warnings using System; @@ -23,6 +23,8 @@ namespace Unity.Cinemachine.Editor class CinemachineUpgradeManager { const string k_UnupgradableTag = " BACKUP - not fully upgradable by CM"; + const string k_RenamePrefix = "__CM__UPGRADER__RENAME__ "; + const string k_CopyPrefix = "__CM__UPGRADER__COPY__ "; UpgradeObjectToCm3 m_ObjectUpgrader; SceneManager m_SceneManager; @@ -40,15 +42,23 @@ class CinemachineUpgradeManager public static void UpgradeSingleObject(GameObject go) { var objectUpgrader = new UpgradeObjectToCm3(); - var notUpgradable = objectUpgrader.UpgradeComponents(go); - objectUpgrader.DeleteObsoleteComponents(go); - - // Report difficult cases - if (notUpgradable != null) + try { - notUpgradable.name = go.name + k_UnupgradableTag; - Debug.LogWarning("Upgrader: " + go.name + " may not have been fully upgraded " + - "automatically. A reference copy of the original was saved to " + notUpgradable.name); + var notUpgradable = objectUpgrader.UpgradeComponents(go); + objectUpgrader.DeleteObsoleteComponents(go); + + // Report difficult cases + if (notUpgradable != null) + { + notUpgradable.name = go.name + k_UnupgradableTag; + Debug.LogWarning("Upgrader: " + go.name + " may not have been fully upgraded " + + "automatically. A reference copy of the original was saved to " + notUpgradable.name); + } + } + catch (Exception e) + { + Debug.LogError(e.Message); + OnUnsuccessfulUpgrade(); } } @@ -67,21 +77,29 @@ public static void UpgradeObjectsInCurrentScene() + "Upgrade scene?", "Upgrade", "Cancel")) { - Thread.Sleep(1); // this is needed so the Display Dialog closes, and lets the progress bar open - EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Initializing...", 0); - var manager = new CinemachineUpgradeManager(false); - var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); - var rootObjects = scene.GetRootGameObjects(); - var upgradable = manager.GetUpgradables( - rootObjects, manager.m_ObjectUpgrader.RootUpgradeComponentTypes, true); - var upgradedObjects = new HashSet(); - EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Upgrading Scene...", 0.5f); - manager.UpgradeNonPrefabs(upgradable, upgradedObjects, null); - UpgradeObjectReferences(rootObjects); - - EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Cleaning up...", 1f); - foreach (var go in upgradedObjects) - manager.m_ObjectUpgrader.DeleteObsoleteComponents(go); + try + { + Thread.Sleep(1); // this is needed so the Display Dialog closes, and lets the progress bar open + EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Initializing...", 0); + var manager = new CinemachineUpgradeManager(false); + var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); + var rootObjects = scene.GetRootGameObjects(); + var upgradable = manager.GetUpgradables( + rootObjects, manager.m_ObjectUpgrader.RootUpgradeComponentTypes, true); + var upgradedObjects = new HashSet(); + EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Upgrading Scene...", 0.5f); + manager.UpgradeNonPrefabs(upgradable, upgradedObjects, null); + UpgradeObjectReferences(rootObjects); + + EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Cleaning up...", 1f); + foreach (var go in upgradedObjects) + manager.m_ObjectUpgrader.DeleteObsoleteComponents(go); + } + catch (Exception e) + { + Debug.LogError(e.Message); + OnUnsuccessfulUpgrade(); + } EditorUtility.ClearProgressBar(); } } @@ -107,26 +125,45 @@ public static void UpgradeProject() + "Upgrade project?", "I made a backup, go ahead", "Cancel")) { - Thread.Sleep(1); // this is needed so the Display Dialog closes, and lets the progress bar open var originalScenePath = EditorSceneManager.GetActiveScene().path; - EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Initializing...", 0); - var manager = new CinemachineUpgradeManager(true); - manager.PrepareUpgrades(out var conversionLinksPerScene, out var timelineRenames); - EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Upgrading Prefabs...", 0.1f); - manager.UpgradePrefabAssets(true); - EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Upgrading Prefabs...", 0.3f); - manager.UpgradeReferencablePrefabInstances(conversionLinksPerScene); - EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Upgrading Prefabs...", 0.6f); - manager.UpgradePrefabAssets(false); - EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Upgrading Scenes...", 0.8f); - manager.UpgradeRemaining(conversionLinksPerScene, timelineRenames); - EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Cleaning up...", 1); - manager.CleanupPrefabAssets(); + try + { + Thread.Sleep(1); // this is needed so the Display Dialog closes, and lets the progress bar open + EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Initializing...", 0.1f); + var manager = new CinemachineUpgradeManager(true); + manager.PrepareUpgrades(out var conversionLinksPerScene, out var timelineRenames); + EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Upgrading Prefabs...", 0.4f); + manager.UpgradePrefabAssets(true); + EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Upgrading Prefabs...", 0.5f); + manager.UpgradeReferencablePrefabInstances(conversionLinksPerScene); + EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Upgrading Prefabs...", 0.6f); + manager.UpgradePrefabAssets(false); + EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Upgrading Scenes...", 0.8f); + manager.UpgradeRemaining(conversionLinksPerScene, timelineRenames); + EditorUtility.DisplayProgressBar(k_ProgressBarTitle, "Cleaning up...", 1); + manager.CleanupPrefabAssets(); + } + catch (Exception e) + { + Debug.LogError(e.Message); + EditorUtility.ClearProgressBar(); + OnUnsuccessfulUpgrade(); + return; + } EditorUtility.ClearProgressBar(); EditorSceneManager.OpenScene(originalScenePath); // re-open scene where the user was before upgrading } } + static void OnUnsuccessfulUpgrade() + { + EditorUtility.DisplayDialog( + "Cinemachine Upgrader", + "The upgrade was unsuccessful, and your project may be correupted. It would be wise to restore the backup.\n\n" + + "Please see the console messages for details.", + "ok"); + } + /// Returns true if any of the objects are prefab instances or prefabs. /// /// @@ -168,29 +205,34 @@ public static bool CurrentSceneUsesPrefabs() /// /// Key: scene index, Value: List of conversion links /// Timeline rename mapping - void PrepareUpgrades(out Dictionary> conversionLinksPerScene, out Dictionary renameMap) + void PrepareUpgrades( + out Dictionary> conversionLinksPerScene, + out Dictionary renameMap) { - conversionLinksPerScene = new Dictionary>(); - renameMap = new Dictionary(); + conversionLinksPerScene = new (); + renameMap = new (); + for (var s = 0; s < m_SceneManager.SceneCount; ++s) { var scene = OpenScene(s); // Make timeline names unique + var timelineManager = new TimelineManager(scene); #if CINEMACHINE_TIMELINE - var directors = TimelineManager.GetPlayableDirectors(scene); - foreach (var director in directors) + foreach (var director in timelineManager.PlayableDirectors) { var originalName = director.name; - director.name = GUID.Generate().ToString(); - renameMap.Add(director.name, originalName); // key = guid, value = originalName + if (!originalName.StartsWith(k_RenamePrefix)) + { + director.name = k_RenamePrefix + originalName + " = " + GUID.Generate().ToString(); + renameMap.Add(director.name, originalName); // key = guid, value = originalName + } } #endif // CopyPrefabInstances, give unique names, create conversion links, collect timeline references // Upgrade prefab instance copies of referencables only var conversionLinks = new List(); - var timelineManager = new TimelineManager(scene); var allPrefabInstances = new List(); for (var p = 0; p < m_PrefabManager.PrefabCount; ++p) @@ -201,9 +243,8 @@ void PrepareUpgrades(out Dictionary> conversionLinksPe } var upgradedObjects = new HashSet(); - var upgradable = - GetUpgradables(allPrefabInstances.ToArray(), m_ObjectUpgrader.RootUpgradeComponentTypes, true); - foreach (var go in upgradable) + var upgradables = GetUpgradables(allPrefabInstances.ToArray(), m_ObjectUpgrader.RootUpgradeComponentTypes, true); + foreach (var go in upgradables) { if (upgradedObjects.Contains(go)) continue; // Ignore if already converted (this can happen in nested prefabs) @@ -215,11 +256,12 @@ void PrepareUpgrades(out Dictionary> conversionLinksPe var convertedCopy = UnityEngine.Object.Instantiate(go); UpgradeObjectComponents(convertedCopy, null); + // Change the object name to something unique so we can find it later var conversionLink = new ConversionLink { originalName = go.name, originalGUIDName = GUID.Generate().ToString(), - convertedGUIDName = GUID.Generate().ToString(), + convertedGUIDName = k_CopyPrefix + GUID.Generate().ToString(), #if CINEMACHINE_TIMELINE timelineReferences = timelineReferences, #endif @@ -230,12 +272,10 @@ void PrepareUpgrades(out Dictionary> conversionLinksPe convertedCopy.name = conversionLink.convertedGUIDName; conversionLinks.Add(conversionLink); } - conversionLinksPerScene.Add(s, conversionLinks); EditorSceneManager.SaveScene(scene); } - m_CurrentSceneOrPrefab = string.Empty; } @@ -254,17 +294,16 @@ void UpgradePrefabAssets(bool upgradeReferencables) for (var p = 0; p < m_PrefabManager.PrefabCount; ++p) { m_CurrentSceneOrPrefab = m_PrefabManager.GetPrefabAssetPath(p); +#if DEBUG_HELPERS + Debug.Log("Upgrading prefab asset: " + m_CurrentSceneOrPrefab); +#endif using var editingScope = new PrefabUtility.EditPrefabContentsScope(m_CurrentSceneOrPrefab); var prefabContents = editingScope.prefabContentsRoot; if (upgradeReferencables ^ UpgradeObjectToCm3.HasReferencableComponent(prefabContents)) continue; -#if CINEMACHINE_TIMELINE - var playableDirectors = prefabContents.GetComponentsInChildren(true).ToList(); - var timelineManager = new TimelineManager(playableDirectors); -#else - var timelineManager = new TimelineManager(); -#endif + var timelineManager = new TimelineManager(prefabContents, m_CurrentSceneOrPrefab); + // Note: this logic relies on the fact FreeLooks will be added first in the component list var components = new List(); foreach (var type in m_ObjectUpgrader.RootUpgradeComponentTypes) @@ -284,9 +323,11 @@ void UpgradePrefabAssets(bool upgradeReferencables) // Fix object references UpgradeObjectReferences(new[] { editingScope.prefabContentsRoot }); + #if CINEMACHINE_TIMELINE // Fix animation references - UpdateAnimationReferences(playableDirectors); + foreach (var playableDirector in timelineManager.PlayableDirectors) + UpdateAnimationBindings(playableDirector); #endif } m_CurrentSceneOrPrefab = string.Empty; @@ -308,7 +349,6 @@ void UpgradeReferencablePrefabInstances(Dictionary> co var timelineManager = new TimelineManager(scene); var upgradedObjects = new HashSet(); UpgradePrefabInstances(upgradedObjects, conversionLinksPerScene[s], timelineManager, true); - EditorSceneManager.SaveScene(scene); } @@ -348,8 +388,9 @@ void UpgradeRemaining( UpgradeObjectComponents(go, null); #if CINEMACHINE_TIMELINE - var playableDirectors = TimelineManager.GetPlayableDirectors(scene); - UpdateAnimationReferences(playableDirectors); + // Fix animation references + foreach (var playableDirector in timelineManager.PlayableDirectors) + UpdateAnimationBindings(playableDirector); #endif UpgradeObjectReferences(rootObjects); @@ -359,7 +400,7 @@ void UpgradeRemaining( #if CINEMACHINE_TIMELINE // Restore timeline names - foreach (var director in playableDirectors) + foreach (var director in timelineManager.PlayableDirectors) { if (timelineRenames.ContainsKey(director.name)) // search based on guid name { @@ -371,7 +412,6 @@ void UpgradeRemaining( #endif EditorSceneManager.SaveScene(scene); } - m_CurrentSceneOrPrefab = string.Empty; } @@ -401,8 +441,7 @@ void CleanupPrefabAssets() m_ObjectUpgrader.DeleteObsoleteComponents(c.gameObject); } - var managers = - prefabContents.GetComponentsInChildren(); + var managers = prefabContents.GetComponentsInChildren(); foreach (var manager in managers) { manager.InvalidateCameraCache(); @@ -476,21 +515,28 @@ void UpgradePrefabInstances(HashSet upgradedObjects, ListPlayable directors in the current scene - void UpdateAnimationReferences(List playableDirectors) - { + #if CINEMACHINE_TIMELINE - foreach (var playableDirector in playableDirectors) - { - if (playableDirector == null) - continue; + void UpdateAnimationBindings(PlayableDirector playableDirector) + { + if (playableDirector == null) + return; - var playableAsset = playableDirector.playableAsset; - if (playableAsset is TimelineAsset timelineAsset) + var playableAsset = playableDirector.playableAsset; + if (playableAsset is TimelineAsset timelineAsset) + { + var tracks = timelineAsset.GetOutputTracks(); + foreach (var track in tracks) { - var tracks = timelineAsset.GetOutputTracks(); - foreach (var track in tracks) + if (track is AnimationTrack animationTrack) { - if (track is AnimationTrack animationTrack) + var binding = playableDirector.GetGenericBinding(track); +#if DEBUG_HELPERS + if (binding == null) { - var trackAnimator = playableDirector.GetGenericBinding(track) as Animator; - if (animationTrack.inClipMode) + Debug.Log("Binding is null for " + + GetFullName(playableDirector.gameObject, m_CurrentSceneOrPrefab) + ", track:" + track.name + + ", PlayableAsset=" + playableAsset.name); + } +#endif + if (binding is Animator trackAnimator) + { + if (!animationTrack.inClipMode) + m_ObjectUpgrader.ProcessAnimationClip(animationTrack.infiniteClip, trackAnimator); //uses recorded clip + else { var clips = animationTrack.GetClips(); var animationClips = clips .Select(c => c.asset) //animation clip is stored in the clip's asset .OfType() //need to cast to the correct asset type .Select(asset => asset.clip); //finally we get an animation clip! - foreach (var animationClip in animationClips) m_ObjectUpgrader.ProcessAnimationClip(animationClip, trackAnimator); } - else //uses recorded clip - m_ObjectUpgrader.ProcessAnimationClip(animationTrack.infiniteClip, trackAnimator); } } } } -#endif } +#endif CinemachineUpgradeManager(bool initPrefabManager) { @@ -605,15 +657,14 @@ void UpdateAnimationReferences(List playableDirectors) Scene OpenScene(int sceneIndex) { - var path = m_SceneManager.GetScenePath(sceneIndex); + m_CurrentSceneOrPrefab = m_SceneManager.GetScenePath(sceneIndex); #if DEBUG_HELPERS - Debug.Log("Opening scene: " + m_SceneManager.GetScenePath(s)); + Debug.Log("Opening scene: " + m_CurrentSceneOrPrefab); #endif - m_CurrentSceneOrPrefab = path; - return EditorSceneManager.OpenScene(path, OpenSceneMode.Single); + return EditorSceneManager.OpenScene(m_CurrentSceneOrPrefab, OpenSceneMode.Single); } - string GetFullName(GameObject go) + static string GetFullName(GameObject go, string pathToRoot) { string path = go.name; while (go.transform.parent != null) @@ -621,7 +672,7 @@ string GetFullName(GameObject go) go = go.transform.parent.gameObject; path = go.name + "/" + path; } - return m_CurrentSceneOrPrefab + "/" + path; + return pathToRoot + "/" + path; } /// @@ -650,7 +701,7 @@ GameObject UpgradeObjectComponents(GameObject go, TimelineManager timelineManage if (notUpgradable != null) { notUpgradable.name = go.name + k_UnupgradableTag; - Debug.LogWarning("Upgrader: " + GetFullName(go) + " may not have been fully upgraded " + + Debug.LogWarning("Upgrader: " + GetFullName(go, m_CurrentSceneOrPrefab) + " may not have been fully upgraded " + "automatically. A reference copy of the original was saved to " + notUpgradable.name); } @@ -826,42 +877,48 @@ public static List FindAllInstancesOfPrefabEvenInNestedPrefabs( class TimelineManager { #if !CINEMACHINE_TIMELINE - public TimelineManager() {} + public TimelineManager(GameObject root, string pathToRoot) {} public TimelineManager(Scene scene) {} #else - Dictionary> m_CmShotsToUpdate; + struct Item { public string Name; public List Shots; } + Dictionary m_ShotsToUpdate; + List m_PlayableDirectors; + string m_PathToRootObject; - public TimelineManager(List playableDirectors) - { - Initialize(playableDirectors); - } + public List PlayableDirectors => m_PlayableDirectors; public TimelineManager(Scene scene) { - Initialize(GetPlayableDirectors(scene)); + m_PathToRootObject = scene.path; + m_PlayableDirectors = new List(); + foreach (var go in scene.GetRootGameObjects()) + m_PlayableDirectors.AddRange(go.GetComponentsInChildren(true).ToList()); + PruneDuplicates(); + CollectShotsToUpdate(); } - public static List GetPlayableDirectors(Scene scene) + public TimelineManager(GameObject root, string pathToRoot) { - var playableDirectors = new List(); - - var rootObjects = scene.GetRootGameObjects(); - foreach (var go in rootObjects) - playableDirectors.AddRange(go.GetComponentsInChildren(true).ToList()); + m_PathToRootObject = pathToRoot; + m_PlayableDirectors = root.GetComponentsInChildren(true).ToList(); + PruneDuplicates(); + CollectShotsToUpdate(); + } - return playableDirectors; + void PruneDuplicates() + { + for (int i = m_PlayableDirectors.Count - 1; i >= 0; --i) + if (m_PlayableDirectors[i].name.StartsWith(k_CopyPrefix)) + m_PlayableDirectors.RemoveAt(i); } - void Initialize(List playableDirectors) + void CollectShotsToUpdate() { - m_CmShotsToUpdate = new Dictionary>(); + m_ShotsToUpdate = new (); // collect all cmShots that may require a reference update - foreach (var playableDirector in playableDirectors) + foreach (var playableDirector in m_PlayableDirectors) { - if (playableDirector == null) - continue; - var playableAsset = playableDirector.playableAsset; if (playableAsset is TimelineAsset timelineAsset) { @@ -875,10 +932,10 @@ void Initialize(List playableDirectors) { if (clip.asset is CinemachineShot cmShot) { - if (!m_CmShotsToUpdate.ContainsKey(playableDirector)) - m_CmShotsToUpdate.Add(playableDirector, new List()); - - m_CmShotsToUpdate[playableDirector].Add(cmShot); + if (!m_ShotsToUpdate.ContainsKey(playableDirector)) + m_ShotsToUpdate.Add(playableDirector, new () + { Name = playableDirector.name, Shots = new () }); + m_ShotsToUpdate[playableDirector].Shots.Add(cmShot); } } } @@ -891,12 +948,13 @@ void Initialize(List playableDirectors) /// Updates timeline reference with the upgraded vcam. This is called after each /// vcam is upgraded, but before the obsolete component is deleted. /// - public void UpdateTimelineReference(CinemachineVirtualCameraBase oldComponent, + public void UpdateTimelineReference( + CinemachineVirtualCameraBase oldComponent, CinemachineVirtualCameraBase upgraded) { - foreach (var (director, cmShots) in m_CmShotsToUpdate) + foreach (var (director, items) in m_ShotsToUpdate) { - foreach (var cmShot in cmShots) + foreach (var cmShot in items.Shots) { var exposedRef = cmShot.VirtualCamera; var vcam = exposedRef.Resolve(director); @@ -908,15 +966,21 @@ public void UpdateTimelineReference(CinemachineVirtualCameraBase oldComponent, public void UpdateTimelineReference(CinemachineVirtualCameraBase upgraded, ConversionLink link) { - foreach (var (director, cmShots) in m_CmShotsToUpdate) + foreach (var (director, items) in m_ShotsToUpdate) { + if (director == null) + continue; var references = link.timelineReferences; foreach (var reference in references) { if (reference.directorName != director.name) + { +#if DEBUG_HELPERS + Debug.Log("Skipping reference for " + reference.directorName + " because it is not for " + director.name); +#endif continue; // ignore references that are not for this director - - foreach (var cmShot in cmShots) + } + foreach (var cmShot in items.Shots) { var exposedRef = cmShot.VirtualCamera; if (exposedRef.exposedName == reference.exposedReference.exposedName) @@ -929,9 +993,9 @@ public void UpdateTimelineReference(CinemachineVirtualCameraBase upgraded, Conve public List GetTimelineReferences(CinemachineVirtualCameraBase vcam) { var references = new List(); - foreach (var (director, cmShots) in m_CmShotsToUpdate) + foreach (var (director, items) in m_ShotsToUpdate) { - foreach (var cmShot in cmShots) + foreach (var cmShot in items.Shots) { var exposedRef = cmShot.VirtualCamera; if (vcam == exposedRef.Resolve(director)) diff --git a/com.unity.cinemachine/Editor/Upgrader/UpgradeObjectToCm3.Data.cs b/com.unity.cinemachine/Editor/Upgrader/UpgradeObjectToCm3.Data.cs index 05b72888c..f110372d9 100644 --- a/com.unity.cinemachine/Editor/Upgrader/UpgradeObjectToCm3.Data.cs +++ b/com.unity.cinemachine/Editor/Upgrader/UpgradeObjectToCm3.Data.cs @@ -235,6 +235,35 @@ public static bool HasReferencableComponent(UnityEngine.GameObject go) { { "XAxis.Value", new("HorizontalAxis.Value", typeof(CinemachineOrbitalFollow)) }, { "YAxis.Value", new("VerticalAxis.Value", typeof(CinemachineOrbitalFollow)) }, + { "Lens.GateFit", new("Lens.PhysicalProperties.GateFit", typeof(CinemachineCamera)) }, + { "Lens.LensShift.x", new("Lens.PhysicalProperties.LensShift.x", typeof(CinemachineCamera)) }, + { "Lens.LensShift.y", new("Lens.PhysicalProperties.LensShift.y", typeof(CinemachineCamera)) }, + { "Lens.FocusDistance", new("Lens.PhysicalProperties.FocusDistance", typeof(CinemachineCamera)) }, + { "Lens.Iso", new("Lens.PhysicalProperties.Iso", typeof(CinemachineCamera)) }, + { "Lens.ShutterSpeed", new("Lens.PhysicalProperties.ShutterSpeed", typeof(CinemachineCamera)) }, + { "Lens.Aperture", new("Lens.PhysicalProperties.Aperture", typeof(CinemachineCamera)) }, + { "Lens.BladeCount", new("Lens.PhysicalProperties.BladeCount", typeof(CinemachineCamera)) }, + { "Lens.Curvature.x", new("Lens.PhysicalProperties.Curvature.x", typeof(CinemachineCamera)) }, + { "Lens.Curvature.y", new("Lens.PhysicalProperties.Curvature.y", typeof(CinemachineCamera)) }, + { "Lens.BarrelClipping", new("Lens.PhysicalProperties.BarrelClipping", typeof(CinemachineCamera)) }, + { "Lens.Anamorphism", new("Lens.PhysicalProperties.Anamorphism", typeof(CinemachineCamera)) }, + } + }, + { + typeof(CinemachineVirtualCamera), new Dictionary> + { + { "Lens.GateFit", new("Lens.PhysicalProperties.GateFit", typeof(CinemachineCamera)) }, + { "Lens.LensShift.x", new("Lens.PhysicalProperties.LensShift.x", typeof(CinemachineCamera)) }, + { "Lens.LensShift.y", new("Lens.PhysicalProperties.LensShift.y", typeof(CinemachineCamera)) }, + { "Lens.FocusDistance", new("Lens.PhysicalProperties.FocusDistance", typeof(CinemachineCamera)) }, + { "Lens.Iso", new("Lens.PhysicalProperties.Iso", typeof(CinemachineCamera)) }, + { "Lens.ShutterSpeed", new("Lens.PhysicalProperties.ShutterSpeed", typeof(CinemachineCamera)) }, + { "Lens.Aperture", new("Lens.PhysicalProperties.Aperture", typeof(CinemachineCamera)) }, + { "Lens.BladeCount", new("Lens.PhysicalProperties.BladeCount", typeof(CinemachineCamera)) }, + { "Lens.Curvature.x", new("Lens.PhysicalProperties.Curvature.x", typeof(CinemachineCamera)) }, + { "Lens.Curvature.y", new("Lens.PhysicalProperties.Curvature.y", typeof(CinemachineCamera)) }, + { "Lens.BarrelClipping", new("Lens.PhysicalProperties.BarrelClipping", typeof(CinemachineCamera)) }, + { "Lens.Anamorphism", new("Lens.PhysicalProperties.Anamorphism", typeof(CinemachineCamera)) }, } }, { diff --git a/com.unity.cinemachine/Editor/Upgrader/UpgradeObjectToCm3.cs b/com.unity.cinemachine/Editor/Upgrader/UpgradeObjectToCm3.cs index 7016ade9a..bf9beb1fc 100644 --- a/com.unity.cinemachine/Editor/Upgrader/UpgradeObjectToCm3.cs +++ b/com.unity.cinemachine/Editor/Upgrader/UpgradeObjectToCm3.cs @@ -39,7 +39,7 @@ public GameObject UpgradeComponents(GameObject go) // Is it a path? if (go.TryGetComponent(out CinemachinePathBase path)) UpgradePath(path); - else + else if (!go.TryGetComponent(out _)) { // It's some kind of vcam. Check for FreeLook first because it has // hidden child VirtualCameras and we need to remove them @@ -160,14 +160,14 @@ public void ProcessAnimationClip(AnimationClip animationClip, Animator trackAnim { // if type is not in class upgrade map, then we won't change binding if (!ClassUpgradeMap.ContainsKey(previousBinding.type)) - break; + continue; var newBinding = previousBinding; // upgrade type based on mapping newBinding.type = ClassUpgradeMap[previousBinding.type]; // clean path pointing to old structure where vcam components lived on a hidden child gameObject - if (previousBinding.path.Contains("cm")) + if (previousBinding.path.EndsWith("cm")) { var path = previousBinding.path; @@ -176,7 +176,7 @@ public void ProcessAnimationClip(AnimationClip animationClip, Animator trackAnim newBinding.path = path.Substring(0, index); } - if (previousBinding.path.Contains("Rig")) + if (previousBinding.path.EndsWith("Rig")) { var path = newBinding.path; //path is either xRig only, or someParent/someOtherParent/.../xRig. In the second case, we need to remove /xRig, thus -1 @@ -193,7 +193,7 @@ static int FindRig(string path) } // clean old convention - if (previousBinding.propertyName.Contains("m_")) + if (previousBinding.propertyName.StartsWith("m_")) { var propertyName = previousBinding.propertyName; newBinding.propertyName = propertyName.Replace("m_", string.Empty); @@ -228,6 +228,10 @@ static int FindRig(string path) } } +#if DEBUG_HELPERS + Debug.Log(previousBinding.path + "." + previousBinding.type.Name + "." + previousBinding.propertyName + + " -> " + newBinding.path + "." + newBinding.type.Name + "." + newBinding.propertyName); +#endif var curve = AnimationUtility.GetEditorCurve(animationClip, previousBinding); //keep existing curves AnimationUtility.SetEditorCurve(animationClip, previousBinding, null); //remove previous binding AnimationUtility.SetEditorCurve(animationClip, newBinding, curve); //set new binding @@ -311,7 +315,7 @@ static GameObject UpgradeVcam(CinemachineVirtualCamera vcam) cmCamera.Follow = vcam.m_Follow; cmCamera.LookAt = vcam.m_LookAt; cmCamera.Target.CustomLookAtTarget = vcam.m_Follow != vcam.m_LookAt; - cmCamera.Lens = vcam.Lens; + cmCamera.Lens = vcam.m_Lens.ToLensSettings(); cmCamera.BlendHint = vcam.BlendHint; if (vcam.m_OnCameraLiveEvent.GetPersistentEventCount() > 0) { @@ -512,17 +516,19 @@ static void ConvertFreelookLens( CinemachineCamera cmCamera, CinemachineFreeLookModifier freeLookModifier) { if (freelook.m_CommonLens) - cmCamera.Lens = freelook.Lens; + cmCamera.Lens = freelook.m_Lens.ToLensSettings(); else { - cmCamera.Lens = freelook.GetRig(1).Lens; - if (!LensSettings.AreEqual(ref freelook.GetRig(1).Lens, ref freelook.GetRig(0).Lens) - || !LensSettings.AreEqual(ref freelook.GetRig(1).Lens, ref freelook.GetRig(2).Lens)) + cmCamera.Lens = freelook.GetRig(1).m_Lens.ToLensSettings(); + var lens0 = freelook.GetRig(0).m_Lens.ToLensSettings(); + var lens2 = freelook.GetRig(2).m_Lens.ToLensSettings(); + if (!LensSettings.AreEqual(ref cmCamera.Lens, ref lens0) + || !LensSettings.AreEqual(ref cmCamera.Lens, ref lens2)) { freeLookModifier.Modifiers.Add(new CinemachineFreeLookModifier.LensModifier { - Top = freelook.GetRig(0).Lens, - Bottom = freelook.GetRig(2).Lens + Top = lens0, + Bottom = lens2 }); } } diff --git a/com.unity.cinemachine/Runtime/Behaviours/CinemachineClearShot.cs b/com.unity.cinemachine/Runtime/Behaviours/CinemachineClearShot.cs index 1bdec9faa..ece596764 100644 --- a/com.unity.cinemachine/Runtime/Behaviours/CinemachineClearShot.cs +++ b/com.unity.cinemachine/Runtime/Behaviours/CinemachineClearShot.cs @@ -70,17 +70,20 @@ protected internal override void PerformLegacyUpgrade(int streamedVersion) base.PerformLegacyUpgrade(streamedVersion); if (streamedVersion < 20220721) { - DefaultTarget = new DefaultTargetSettings - { - Enabled = true, - Target = new CameraTarget - { - LookAtTarget = m_LegacyLookAt, - TrackingTarget = m_LegacyFollow, - CustomLookAtTarget = m_LegacyLookAt != m_LegacyFollow - } - }; - m_LegacyLookAt = m_LegacyFollow = null; + if (m_LegacyLookAt != null || m_LegacyFollow != null) + { + DefaultTarget = new DefaultTargetSettings + { + Enabled = true, + Target = new CameraTarget + { + LookAtTarget = m_LegacyLookAt, + TrackingTarget = m_LegacyFollow, + CustomLookAtTarget = m_LegacyLookAt != m_LegacyFollow + } + }; + m_LegacyLookAt = m_LegacyFollow = null; + } } } diff --git a/com.unity.cinemachine/Runtime/Behaviours/CinemachineSequencerCamera.cs b/com.unity.cinemachine/Runtime/Behaviours/CinemachineSequencerCamera.cs index 6c6eb3a09..4ca3518a3 100644 --- a/com.unity.cinemachine/Runtime/Behaviours/CinemachineSequencerCamera.cs +++ b/com.unity.cinemachine/Runtime/Behaviours/CinemachineSequencerCamera.cs @@ -86,17 +86,20 @@ protected internal override void PerformLegacyUpgrade(int streamedVersion) base.PerformLegacyUpgrade(streamedVersion); if (streamedVersion < 20220721) { - DefaultTarget = new DefaultTargetSettings - { - Enabled = true, - Target = new CameraTarget - { - LookAtTarget = m_LegacyLookAt, - TrackingTarget = m_LegacyFollow, - CustomLookAtTarget = m_LegacyLookAt != m_LegacyFollow - } - }; - m_LegacyLookAt = m_LegacyFollow = null; + if (m_LegacyLookAt != null || m_LegacyFollow != null) + { + DefaultTarget = new DefaultTargetSettings + { + Enabled = true, + Target = new CameraTarget + { + LookAtTarget = m_LegacyLookAt, + TrackingTarget = m_LegacyFollow, + CustomLookAtTarget = m_LegacyLookAt != m_LegacyFollow + } + }; + m_LegacyLookAt = m_LegacyFollow = null; + } } } diff --git a/com.unity.cinemachine/Runtime/Behaviours/CinemachineStateDrivenCamera.cs b/com.unity.cinemachine/Runtime/Behaviours/CinemachineStateDrivenCamera.cs index 1711b1e64..63807abb1 100644 --- a/com.unity.cinemachine/Runtime/Behaviours/CinemachineStateDrivenCamera.cs +++ b/com.unity.cinemachine/Runtime/Behaviours/CinemachineStateDrivenCamera.cs @@ -111,17 +111,20 @@ protected internal override void PerformLegacyUpgrade(int streamedVersion) base.PerformLegacyUpgrade(streamedVersion); if (streamedVersion < 20220721) { - DefaultTarget = new DefaultTargetSettings - { - Enabled = true, - Target = new CameraTarget - { - LookAtTarget = m_LegacyLookAt, - TrackingTarget = m_LegacyFollow, - CustomLookAtTarget = m_LegacyLookAt != m_LegacyFollow - } - }; - m_LegacyLookAt = m_LegacyFollow = null; + if (m_LegacyLookAt != null || m_LegacyFollow != null) + { + DefaultTarget = new DefaultTargetSettings + { + Enabled = true, + Target = new CameraTarget + { + LookAtTarget = m_LegacyLookAt, + TrackingTarget = m_LegacyFollow, + CustomLookAtTarget = m_LegacyLookAt != m_LegacyFollow + } + }; + m_LegacyLookAt = m_LegacyFollow = null; + } } } diff --git a/com.unity.cinemachine/Runtime/Core/CinemachineVirtualCameraBase.cs b/com.unity.cinemachine/Runtime/Core/CinemachineVirtualCameraBase.cs index 165120ef8..98cd55f40 100644 --- a/com.unity.cinemachine/Runtime/Core/CinemachineVirtualCameraBase.cs +++ b/com.unity.cinemachine/Runtime/Core/CinemachineVirtualCameraBase.cs @@ -137,11 +137,17 @@ public enum StandbyUpdateMode internal protected virtual void PerformLegacyUpgrade(int streamedVersion) { if (streamedVersion < 20220601) - Priority.Value = m_LegacyPriority; + { + if (m_LegacyPriority != 0) + { + Priority.Value = m_LegacyPriority; + m_LegacyPriority = 0; + } + } } [HideInInspector, SerializeField, FormerlySerializedAs("m_Priority")] - int m_LegacyPriority = 10; + int m_LegacyPriority = 0; //============================================================================ @@ -525,6 +531,11 @@ protected virtual void OnDestroy() protected virtual void Start() { m_WasStarted = true; + + // Perform legacy upgrade if necessary + if (m_StreamingVersion < CinemachineCore.kStreamingVersion) + PerformLegacyUpgrade(m_StreamingVersion); + m_StreamingVersion = CinemachineCore.kStreamingVersion; } /// Base class implementation adds the virtual camera from the priority queue. diff --git a/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs index 0b532a3d9..8c2dfa87f 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs @@ -42,7 +42,8 @@ public class CinemachineFreeLook : CinemachineVirtualCameraBase, AxisState.IRequ [Tooltip("Specifies the lens properties of this Virtual Camera. This generally " + "mirrors the Unity Camera's lens settings, and will be used to drive the " + "Unity camera when the vcam is active")] - public LensSettings Lens = LensSettings.Default; + [FormerlySerializedAs("m_LensAttributes")] + public LegacyLensSettings m_Lens = LegacyLensSettings.Default; /// Hint for transitioning to and from this CinemachineCamera. Hints can be combined, although /// not all combinations make sense. In the case of conflicting hints, Cinemachine will @@ -135,10 +136,6 @@ struct LegacyTransitionParams } [SerializeField, HideInInspector] LegacyTransitionParams m_LegacyTransitions; - [FormerlySerializedAs("m_LensAttributes")] - [FormerlySerializedAs("m_Lens")] - LegacyLensSettings m_LegacyLens; - internal protected override void PerformLegacyUpgrade(int streamedVersion) { base.PerformLegacyUpgrade(streamedVersion); @@ -172,8 +169,6 @@ internal protected override void PerformLegacyUpgrade(int streamedVersion) m_LegacyTransitions.m_OnCameraLive = null; } } - if (streamedVersion < 20230301) - Lens = m_LegacyLens.ToLensSettings(); } /// Enforce bounds for fields, when changed in inspector. @@ -183,7 +178,7 @@ void OnValidate() m_XAxis.Validate(); m_RecenterToTargetHeading.Validate(); m_YAxisRecentering.Validate(); - Lens.Validate(); + m_Lens.Validate(); InvalidateRigCache(); @@ -807,7 +802,7 @@ void PushSettingsToRigs() for (int i = 0; i < m_Rigs.Length; ++i) { if (m_CommonLens) - m_Rigs[i].Lens = Lens; + m_Rigs[i].m_Lens = m_Lens; // If we just deserialized from a legacy version, // pull the orbits and targets from the rigs @@ -850,9 +845,12 @@ private float GetYAxisValue() return (range > UnityVectorExtensions.Epsilon) ? m_YAxis.Value / range : 0.5f; } + private LensSettings m_LensSettings; + private CameraState CalculateNewState(Vector3 worldUp, float deltaTime) { - CameraState state = PullStateFromVirtualCamera(worldUp, ref Lens); + m_LensSettings = m_Lens.ToLensSettings(); + CameraState state = PullStateFromVirtualCamera(worldUp, ref m_LensSettings); m_YAxisRecentering.DoRecentering(ref m_YAxis, deltaTime, 0.5f); // Blend from the appropriate rigs diff --git a/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs index be69fd10e..3a6c7c839 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs @@ -43,7 +43,8 @@ public class CinemachineVirtualCamera : CinemachineVirtualCameraBase, AxisState. [Tooltip("Specifies the lens properties of this Virtual Camera. This generally " + "mirrors the Unity Camera's lens settings, and will be used to drive the " + "Unity camera when the vcam is active.")] - public LensSettings Lens = LensSettings.Default; + [FormerlySerializedAs("m_LensAttributes")] + public LegacyLensSettings m_Lens = LegacyLensSettings.Default; /// Hint for transitioning to and from this CinemachineCamera. Hints can be combined, although /// not all combinations make sense. In the case of conflicting hints, Cinemachine will @@ -77,10 +78,6 @@ struct LegacyTransitionParams [FormerlySerializedAs("m_Transitions")] [SerializeField, HideInInspector] LegacyTransitionParams m_LegacyTransitions; - [FormerlySerializedAs("m_LensAttributes")] - [FormerlySerializedAs("m_Lens")] - LegacyLensSettings m_LegacyLens; - internal protected override void PerformLegacyUpgrade(int streamedVersion) { base.PerformLegacyUpgrade(streamedVersion); @@ -105,8 +102,6 @@ internal protected override void PerformLegacyUpgrade(int streamedVersion) m_LegacyTransitions.m_OnCameraLive = null; } } - if (streamedVersion < 20230301) - Lens = m_LegacyLens.ToLensSettings(); } // =============================================================== @@ -186,7 +181,8 @@ override public void InternalUpdateCameraState(Vector3 worldUp, float deltaTime) override protected void OnEnable() { base.OnEnable(); - m_State = PullStateFromVirtualCamera(Vector3.up, ref Lens); + m_LensSettings = m_Lens.ToLensSettings(); + m_State = PullStateFromVirtualCamera(Vector3.up, ref m_LensSettings); InvalidateComponentPipeline(); } @@ -206,7 +202,7 @@ protected override void OnDestroy() /// Enforce bounds for fields, when changed in inspector. protected void OnValidate() { - Lens.Validate(); + m_Lens.Validate(); } void OnTransformChildrenChanged() @@ -463,6 +459,7 @@ static internal void SetFlagsForHiddenChild(GameObject child) } } + private LensSettings m_LensSettings; private Transform mCachedLookAtTarget; private CinemachineVirtualCameraBase mCachedLookAtTargetVcam; private CameraState CalculateNewState(Vector3 worldUp, float deltaTime) @@ -471,7 +468,8 @@ private CameraState CalculateNewState(Vector3 worldUp, float deltaTime) LookAtTargetAttachment = 1; // Initialize the camera state, in case the game object got moved in the editor - CameraState state = PullStateFromVirtualCamera(worldUp, ref Lens); + m_LensSettings = m_Lens.ToLensSettings(); + CameraState state = PullStateFromVirtualCamera(worldUp, ref m_LensSettings); Transform lookAtTarget = LookAt; if (lookAtTarget != mCachedLookAtTarget) diff --git a/com.unity.cinemachine/Runtime/Deprecated/LegacyLensSettings.cs b/com.unity.cinemachine/Runtime/Deprecated/LegacyLensSettings.cs index cf216f470..e748b27d3 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/LegacyLensSettings.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/LegacyLensSettings.cs @@ -5,28 +5,48 @@ namespace Unity.Cinemachine { /// Used to read in CM2 LensSettings + [Obsolete("LegacyLensSettings is deprecated. Use LensSettings instead.")] [Serializable] - internal struct LegacyLensSettings + public struct LegacyLensSettings { + /// Obsolete. public float FieldOfView; + /// Obsolete. public float OrthographicSize; + /// Obsolete. public float NearClipPlane; + /// Obsolete. public float FarClipPlane; + /// Obsolete. public float Dutch; + /// Obsolete. public LensSettings.OverrideModes ModeOverride; + /// Obsolete. public Camera.GateFitMode GateFit; - public Vector2 m_SensorSize; + /// Obsolete. + [HideInInspector] public Vector2 m_SensorSize; + /// Obsolete. public Vector2 LensShift; + /// Obsolete. public float FocusDistance; + /// Obsolete. public int Iso; + /// Obsolete. public float ShutterSpeed; + /// Obsolete. public float Aperture; + /// Obsolete. public int BladeCount; + /// Obsolete. public Vector2 Curvature; + /// Obsolete. public float BarrelClipping; + /// Obsolete. public float Anamorphism; + /// Convert to LensSettings + /// Lens Settings representation of the LegacyLensSettings object public LensSettings ToLensSettings() { var lens = new LensSettings @@ -42,7 +62,6 @@ public LensSettings ToLensSettings() lens.PhysicalProperties.GateFit = GateFit; lens.PhysicalProperties.SensorSize = m_SensorSize; lens.PhysicalProperties.LensShift = LensShift; -#if CINEMACHINE_HDRP lens.PhysicalProperties.FocusDistance = FocusDistance; lens.PhysicalProperties.Iso = Iso; lens.PhysicalProperties.ShutterSpeed = ShutterSpeed; @@ -51,9 +70,69 @@ public LensSettings ToLensSettings() lens.PhysicalProperties.Curvature = Curvature; lens.PhysicalProperties.BarrelClipping = BarrelClipping; lens.PhysicalProperties.Anamorphism = Anamorphism; -#endif return lens; } + + /// Obsolete + /// LensSettings to copy from + public void SetFromLensSettings(LensSettings src) + { + FieldOfView = src.FieldOfView; + OrthographicSize = src.OrthographicSize; + NearClipPlane = src.NearClipPlane; + FarClipPlane = src.FarClipPlane; + Dutch = src.Dutch; + ModeOverride = src.ModeOverride; + + GateFit = src.PhysicalProperties.GateFit; + m_SensorSize = src.PhysicalProperties.SensorSize; + LensShift = src.PhysicalProperties.LensShift; + FocusDistance = src.PhysicalProperties.FocusDistance; + Iso = src.PhysicalProperties.Iso; + ShutterSpeed = src.PhysicalProperties.ShutterSpeed; + Aperture = src.PhysicalProperties.Aperture; + BladeCount = src.PhysicalProperties.BladeCount; + Curvature = src.PhysicalProperties.Curvature; + BarrelClipping = src.PhysicalProperties.BarrelClipping; + Anamorphism = src.PhysicalProperties.Anamorphism; + } + + /// Make sure legacy lens settings are sane. Call this from OnValidate(). + public void Validate() + { + FarClipPlane = Mathf.Max(FarClipPlane, NearClipPlane + 0.001f); + FieldOfView = Mathf.Clamp(FieldOfView, 0.01f, 179f); + FocusDistance = Mathf.Max(FocusDistance, 0.01f); + ShutterSpeed = Mathf.Max(0, ShutterSpeed); + Aperture = Mathf.Clamp(Aperture, Camera.kMinAperture, Camera.kMaxAperture); + BladeCount = Mathf.Clamp(BladeCount, Camera.kMinBladeCount, Camera.kMaxBladeCount); + BarrelClipping = Mathf.Clamp01(BarrelClipping); + Curvature.x = Mathf.Clamp(Curvature.x, Camera.kMinAperture, Camera.kMaxAperture); + Curvature.y = Mathf.Clamp(Curvature.y, Curvature.x, Camera.kMaxAperture); + Anamorphism = Mathf.Clamp(Anamorphism, -1, 1); + } + + /// Obsolete. Default Legacy Lens Settings + public static LegacyLensSettings Default => new () + { + FieldOfView = 40f, + OrthographicSize = 10f, + NearClipPlane = 0.1f, + FarClipPlane = 5000f, + Dutch = 0, + ModeOverride = LensSettings.OverrideModes.None, + m_SensorSize = new Vector2(21.946f, 16.002f), + GateFit = Camera.GateFitMode.Horizontal, + FocusDistance = 10, + LensShift = Vector2.zero, + Iso = 200, + ShutterSpeed = 0.005f, + Aperture = 16, + BladeCount = 5, + Curvature = new Vector2(2, 11), + BarrelClipping = 0.25f, + Anamorphism = 0 + }; } } #endif diff --git a/com.unity.cinemachine/Tests/Runtime/ClearShotTests.cs b/com.unity.cinemachine/Tests/Runtime/ClearShotTests.cs index df89be355..47461f7f2 100644 --- a/com.unity.cinemachine/Tests/Runtime/ClearShotTests.cs +++ b/com.unity.cinemachine/Tests/Runtime/ClearShotTests.cs @@ -29,7 +29,7 @@ public override void SetUp() m_ClearShot.LookAt = m_Character.transform; var clearShotCollider = clearShotHolder.GetComponent(); clearShotCollider.ShotQualityEvaluation.Enabled = true; - clearShotCollider.MinimumDistanceFromTarget = 0.1f; + clearShotCollider.AvoidObstacles.Enabled = false; // a stationary vcam1 with a hard lookat var vcam1Holder = CreateGameObject("CM Vcam1", typeof(CinemachineCamera)); @@ -47,9 +47,9 @@ public override void SetUp() m_Vcam2.Priority.Value = 10; // a "wall" composed of a single quad that partially obscures vcam1, but not vcam2 - var wall = CreatePrimitive(PrimitiveType.Quad); - wall.transform.SetPositionAndRotation(new Vector3(0, 0, 4), Quaternion.Euler(0, 180, 0)); - wall.transform.localScale = new Vector3(2, 2, 2); + var wall = CreatePrimitive(PrimitiveType.Cube); + wall.transform.SetPositionAndRotation(new Vector3(0, 0, 4), Quaternion.identity); + wall.transform.localScale = new Vector3(2, 2, 0.2f); } static IEnumerable ClearShotTestCases @@ -58,7 +58,7 @@ static IEnumerable ClearShotTestCases { yield return new TestCaseData(new Vector3(100, 0, 1), "CM Vcam1").Returns(null); yield return new TestCaseData(new Vector3(5, 0, 1), "CM Vcam1").Returns(null); - yield return new TestCaseData(new Vector3(0, 0, 1), "CM Vcam2").Returns(null); + yield return new TestCaseData(new Vector3(0, 0, 0), "CM Vcam2").Returns(null); yield return new TestCaseData(new Vector3(-5, 0, 1), "CM Vcam1").Returns(null); yield return new TestCaseData(new Vector3(-100, 0, 1), "CM Vcam1").Returns(null); } @@ -68,9 +68,7 @@ static IEnumerable ClearShotTestCases public IEnumerator TestClearShotSwitchesCameras(Vector3 characterPosition, string expectedVcamName) { m_Character.transform.position = characterPosition; - yield return new WaitForSeconds(0.5f); - Assert.That(m_ClearShot.LiveChild.Name, Is.EqualTo(expectedVcamName)); } }