From 483b1a628d551d04fb54df6b38836c4c0e3e911b Mon Sep 17 00:00:00 2001 From: Gregory Labute Date: Mon, 2 Oct 2023 13:15:01 -0400 Subject: [PATCH 1/4] Fix ListView inspectors --- com.unity.cinemachine/CHANGELOG.md | 8 +++++ .../CinemachineBlenderSettingsEditor.cs | 30 +++++++--------- .../CinemachineSequencerCameraEditor.cs | 34 +++++++++++++------ .../Editors/InputAxisControllerEditor.cs | 8 ++--- .../Utility/CmCameraInspectorUtility.cs | 17 ++++------ 5 files changed, 53 insertions(+), 44 deletions(-) diff --git a/com.unity.cinemachine/CHANGELOG.md b/com.unity.cinemachine/CHANGELOG.md index aaa04d07e..8eb62d949 100644 --- a/com.unity.cinemachine/CHANGELOG.md +++ b/com.unity.cinemachine/CHANGELOG.md @@ -4,6 +4,14 @@ 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.0.0-pre.9] - 2023-10-31 + +### Fixed +- Regresion fix: Sequencer inspector child camera popups were not being populated. +- Regresion fix: Manager Camera's child camera warning icons were not being updated correctly. +- Bugfix: CinemachineInputAxisController editor was missing foldout arrows on the Driven Axis items. + + ## [3.0.0-pre.8] - 2023-09-22 ### Fixed diff --git a/com.unity.cinemachine/Editor/Editors/CinemachineBlenderSettingsEditor.cs b/com.unity.cinemachine/Editor/Editors/CinemachineBlenderSettingsEditor.cs index 230511059..d8ded2e4f 100644 --- a/com.unity.cinemachine/Editor/Editors/CinemachineBlenderSettingsEditor.cs +++ b/com.unity.cinemachine/Editor/Editors/CinemachineBlenderSettingsEditor.cs @@ -68,27 +68,23 @@ public override VisualElement CreateInspectorGUI() list.RefreshItems(); // rebuild the list }); - // Delay to work around a bug in ListView (UUM-27687 and UUM-27688) - list.OnInitialGeometry(() => + list.makeItem = () => new BindableElement { style = { flexDirection = FlexDirection.Row }}; + list.bindItem = (row, index) => { - list.makeItem = () => new BindableElement { style = { flexDirection = FlexDirection.Row }}; - list.bindItem = (row, index) => - { - // Remove children - items get recycled - for (int i = row.childCount - 1; i >= 0; --i) - row.RemoveAt(i); + // Remove children - items get recycled + for (int i = row.childCount - 1; i >= 0; --i) + row.RemoveAt(i); - var def = new CinemachineBlenderSettings.CustomBlend(); - var element = elements.GetArrayElementAtIndex(index); + var def = new CinemachineBlenderSettings.CustomBlend(); + var element = elements.GetArrayElementAtIndex(index); - var from = row.AddChild(CreateCameraPopup(element.FindPropertyRelative(() => def.From))); - var to = row.AddChild(CreateCameraPopup(element.FindPropertyRelative(() => def.To))); - var blend = row.AddChild(new PropertyField(element.FindPropertyRelative(() => def.Blend), "")); - FormatElement(false, from, to, blend); + var from = row.AddChild(CreateCameraPopup(element.FindPropertyRelative(() => def.From))); + var to = row.AddChild(CreateCameraPopup(element.FindPropertyRelative(() => def.To))); + var blend = row.AddChild(new PropertyField(element.FindPropertyRelative(() => def.Blend), "")); + FormatElement(false, from, to, blend); - ((BindableElement)row).BindProperty(element); // bind must be done at the end - }; - }); + ((BindableElement)row).BindProperty(element); // bind must be done at the end + }; // Local function static void FormatElement(bool isHeader, VisualElement e1, VisualElement e2, VisualElement e3) diff --git a/com.unity.cinemachine/Editor/Editors/CinemachineSequencerCameraEditor.cs b/com.unity.cinemachine/Editor/Editors/CinemachineSequencerCameraEditor.cs index 9fa6ee1fa..ca2410831 100644 --- a/com.unity.cinemachine/Editor/Editors/CinemachineSequencerCameraEditor.cs +++ b/com.unity.cinemachine/Editor/Editors/CinemachineSequencerCameraEditor.cs @@ -63,19 +63,9 @@ public override VisualElement CreateInspectorGUI() var element = instructions.GetArrayElementAtIndex(index); var vcamSelProp = element.FindPropertyRelative(() => def.Camera); - var vcamSel = row.AddChild(new PopupField()); + var vcamSel = row.AddChild(new PopupField { name = $"vcamSelector{index}" }); vcamSel.formatListItemCallback = (obj) => obj == null ? "(null)" : obj.name; vcamSel.formatSelectedValueCallback = (obj) => obj == null ? "(null)" : obj.name; - vcamSel.TrackAnyUserActivity(() => - { - if (Target == null) - return; // object deleted - vcamSel.choices ??= new(); - vcamSel.choices.Clear(); - var children = Target.ChildCameras; - for (int i = 0; i < children.Count; ++i) - vcamSel.choices.Add(children[i]); - }); var blend = row.AddChild( new PropertyField(element.FindPropertyRelative(() => def.Blend), "")); @@ -90,6 +80,28 @@ public override VisualElement CreateInspectorGUI() vcamSel.BindProperty(vcamSelProp); }; + // Update the list items + list.TrackAnyUserActivity(() => + { + int index = 0; + var iter = list.itemsSource.GetEnumerator(); + while (iter.MoveNext()) + { + var vcamSel = list.Q>($"vcamSelector{index}"); + if (vcamSel != null) + { + if (Target == null) + return; // object deleted + vcamSel.choices ??= new(); + vcamSel.choices.Clear(); + var children = Target.ChildCameras; + for (int i = 0; i < children.Count; ++i) + vcamSel.choices.Add(children[i]); + } + ++index; + } + }); + // Local function static void FormatInstructionElement(bool isHeader, VisualElement e1, VisualElement e2, VisualElement e3) { diff --git a/com.unity.cinemachine/Editor/Editors/InputAxisControllerEditor.cs b/com.unity.cinemachine/Editor/Editors/InputAxisControllerEditor.cs index 5c80dbde0..bb6e42d93 100644 --- a/com.unity.cinemachine/Editor/Editors/InputAxisControllerEditor.cs +++ b/com.unity.cinemachine/Editor/Editors/InputAxisControllerEditor.cs @@ -136,7 +136,7 @@ public override VisualElement CreatePropertyGUI(SerializedProperty property) foldout.Add(new PropertyField(childProperty)); childProperty.NextVisible(false); } - return new InspectorUtility.FoldoutWithOverlay(foldout, overlay, null); + return new InspectorUtility.FoldoutWithOverlay(foldout, overlay, null) { style = { marginLeft = 12 }}; } } @@ -158,13 +158,11 @@ public override VisualElement CreatePropertyGUI(SerializedProperty property) showBorder = false, showBoundCollectionSize = false, showFoldoutHeader = false, - virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight + virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight, + style = { marginLeft = -12 } }); list.BindProperty(property); - // Delay to work around a bug in ListView (UUM-33402) - list.OnInitialGeometry(() => list.reorderable = false); - var isEmptyMessage = ux.AddChild(new HelpBox( "No applicable components found. Must have one of: " + InspectorUtility.GetAssignableBehaviourNames(typeof(IInputAxisOwner)), diff --git a/com.unity.cinemachine/Editor/Utility/CmCameraInspectorUtility.cs b/com.unity.cinemachine/Editor/Utility/CmCameraInspectorUtility.cs index 43e1b18ee..9b09c0bde 100644 --- a/com.unity.cinemachine/Editor/Utility/CmCameraInspectorUtility.cs +++ b/com.unity.cinemachine/Editor/Utility/CmCameraInspectorUtility.cs @@ -507,7 +507,6 @@ public static void AddChildCameras( for (int i = row.childCount - 1; i >= 0; --i) row.RemoveAt(i); - var warningIcon = row.AddChild(InspectorUtility.MiniHelpIcon("Item is null")); var element = list.itemsSource[index] as CinemachineVirtualCameraBase; row.AddChild(new ObjectField { @@ -518,6 +517,11 @@ public static void AddChildCameras( if (element == null) return; + var warningIcon = row.AddChild(InspectorUtility.MiniHelpIcon("Item is null")); + var warningText = getChildWarning == null ? string.Empty : getChildWarning(element); + warningIcon.tooltip = warningText; + warningIcon.SetVisible(!string.IsNullOrEmpty(warningText)); + var dragger = row.AddChild(new Label(" ")); dragger.AddToClassList("unity-base-field__label--with-dragger"); @@ -540,13 +544,6 @@ public static void AddChildCameras( }); priorityField.TrackPropertyValue(priorityProp, (p) => priorityField.value = p.intValue); priorityField.TrackPropertyValue(enabledProp, (p) => priorityField.value = p.boolValue ? priorityProp.intValue : 0); - - warningIcon.TrackAnyUserActivity(() => - { - var warningText = (getChildWarning == null || element == null) ? string.Empty : getChildWarning(element); - warningIcon.tooltip = warningText; - warningIcon.SetVisible(!string.IsNullOrEmpty(warningText)); - }); }; list.itemsAdded += (added) => @@ -585,10 +582,8 @@ public static void AddChildCameras( // Update child list if (!isMultiSelect) { - var rebuild = list.itemsSource != vcam.ChildCameras || list.itemsSource.Count != vcam.ChildCameras.Count; list.itemsSource = vcam.ChildCameras; - if (rebuild) - list.Rebuild(); + list.Rebuild(); } }); } From fb7a8d35962b2acc53aa351d5826d10d6f3c20a3 Mon Sep 17 00:00:00 2001 From: Gregory Labute Date: Mon, 2 Oct 2023 15:31:25 -0400 Subject: [PATCH 2/4] bugfixes --- .../CinemachineBlenderSettingsEditor.cs | 23 +++++--- .../CinemachineSequencerCameraEditor.cs | 52 ++++++++++--------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/com.unity.cinemachine/Editor/Editors/CinemachineBlenderSettingsEditor.cs b/com.unity.cinemachine/Editor/Editors/CinemachineBlenderSettingsEditor.cs index d8ded2e4f..1f3b460ed 100644 --- a/com.unity.cinemachine/Editor/Editors/CinemachineBlenderSettingsEditor.cs +++ b/com.unity.cinemachine/Editor/Editors/CinemachineBlenderSettingsEditor.cs @@ -76,14 +76,16 @@ public override VisualElement CreateInspectorGUI() row.RemoveAt(i); var def = new CinemachineBlenderSettings.CustomBlend(); - var element = elements.GetArrayElementAtIndex(index); - - var from = row.AddChild(CreateCameraPopup(element.FindPropertyRelative(() => def.From))); - var to = row.AddChild(CreateCameraPopup(element.FindPropertyRelative(() => def.To))); - var blend = row.AddChild(new PropertyField(element.FindPropertyRelative(() => def.Blend), "")); - FormatElement(false, from, to, blend); + var element = index < elements.arraySize ? elements.GetArrayElementAtIndex(index) : null; + if (!IsUnityNull(element)) + { + var from = row.AddChild(CreateCameraPopup(element.FindPropertyRelative(() => def.From))); + var to = row.AddChild(CreateCameraPopup(element.FindPropertyRelative(() => def.To))); + var blend = row.AddChild(new PropertyField(element.FindPropertyRelative(() => def.Blend), "")); + FormatElement(false, from, to, blend); - ((BindableElement)row).BindProperty(element); // bind must be done at the end + ((BindableElement)row).BindProperty(element); // bind must be done at the end + } }; // Local function @@ -123,6 +125,13 @@ VisualElement CreateCameraPopup(SerializedProperty p) return row; } + // Local function + static bool IsUnityNull(object obj) + { + // Checks whether an object is null or Unity pseudo-null + // without having to cast to UnityEngine.Object manually + return obj == null || ((obj is UnityEngine.Object) && ((UnityEngine.Object)obj) == null); + } return ux; } } diff --git a/com.unity.cinemachine/Editor/Editors/CinemachineSequencerCameraEditor.cs b/com.unity.cinemachine/Editor/Editors/CinemachineSequencerCameraEditor.cs index ca2410831..410f80853 100644 --- a/com.unity.cinemachine/Editor/Editors/CinemachineSequencerCameraEditor.cs +++ b/com.unity.cinemachine/Editor/Editors/CinemachineSequencerCameraEditor.cs @@ -41,6 +41,7 @@ public override VisualElement CreateInspectorGUI() var list = container.AddChild(new ListView() { + name = "InstructionList", reorderable = true, reorderMode = ListViewReorderMode.Animated, showAddRemoveFooter = true, @@ -67,8 +68,9 @@ public override VisualElement CreateInspectorGUI() vcamSel.formatListItemCallback = (obj) => obj == null ? "(null)" : obj.name; vcamSel.formatSelectedValueCallback = (obj) => obj == null ? "(null)" : obj.name; - var blend = row.AddChild( - new PropertyField(element.FindPropertyRelative(() => def.Blend), "")); + var blend = row.AddChild(new PropertyField(element.FindPropertyRelative(() => def.Blend), "")); + if (index == 0) + blend.name = "FirstItemBlend"; var hold = row.AddChild( new InspectorUtility.CompactPropertyField(element.FindPropertyRelative(() => def.Hold), " ")); hold.RemoveFromClassList(InspectorUtility.kAlignFieldClass); @@ -80,28 +82,6 @@ public override VisualElement CreateInspectorGUI() vcamSel.BindProperty(vcamSelProp); }; - // Update the list items - list.TrackAnyUserActivity(() => - { - int index = 0; - var iter = list.itemsSource.GetEnumerator(); - while (iter.MoveNext()) - { - var vcamSel = list.Q>($"vcamSelector{index}"); - if (vcamSel != null) - { - if (Target == null) - return; // object deleted - vcamSel.choices ??= new(); - vcamSel.choices.Clear(); - var children = Target.ChildCameras; - for (int i = 0; i < children.Count; ++i) - vcamSel.choices.Add(children[i]); - } - ++index; - } - }); - // Local function static void FormatInstructionElement(bool isHeader, VisualElement e1, VisualElement e2, VisualElement e3) { @@ -126,9 +106,33 @@ static void FormatInstructionElement(bool isHeader, VisualElement e1, VisualElem { if (Target == null) return; // object deleted + var isMultiSelect = targets.Length > 1; multiSelectMsg.SetVisible(isMultiSelect); container.SetVisible(!isMultiSelect); + + // Hide the first blend if not looped + var instructions = container.Q("InstructionList"); + instructions.Q("FirstItemBlend")?.SetEnabled(Target.Loop); + + // Update the list items + int index = 0; + var iter = instructions.itemsSource.GetEnumerator(); + while (iter.MoveNext()) + { + var vcamSel = list.Q>($"vcamSelector{index}"); + if (vcamSel != null) + { + if (Target == null) + return; // object deleted + vcamSel.choices ??= new(); + vcamSel.choices.Clear(); + var children = Target.ChildCameras; + for (int i = 0; i < children.Count; ++i) + vcamSel.choices.Add(children[i]); + } + ++index; + } }); this.AddExtensionsDropdown(ux); From 103f4eb3ee570ef6f7a3bedc9ad9120ebb1e54ef Mon Sep 17 00:00:00 2001 From: Gregory Labute Date: Mon, 2 Oct 2023 15:46:24 -0400 Subject: [PATCH 3/4] minimum Unity is 2022.3.9f1 --- com.unity.cinemachine/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.cinemachine/package.json b/com.unity.cinemachine/package.json index 4d6f785fd..7e93f790a 100644 --- a/com.unity.cinemachine/package.json +++ b/com.unity.cinemachine/package.json @@ -2,8 +2,8 @@ "name": "com.unity.cinemachine", "displayName": "Cinemachine", "version": "3.0.0-pre.8", - "unity": "2022.2", - "unityRelease": "16f1", + "unity": "2022.3", + "unityRelease": "9f1", "description": "Smart camera tools for passionate creators. \n\nCinemachine 3.0 is a newer and better version of Cinemachine, but upgrading an existing project from 2.X will likely require some effort. If you're considering upgrading an older project, please see our upgrade guide in the user manual.", "keywords": [ "camera", From a58b210e086537327d245ab60783758c4d2f2fcf Mon Sep 17 00:00:00 2001 From: Gregory Labute Date: Mon, 2 Oct 2023 16:10:09 -0400 Subject: [PATCH 4/4] Update package.json --- com.unity.cinemachine/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/com.unity.cinemachine/package.json b/com.unity.cinemachine/package.json index 7e93f790a..d68918268 100644 --- a/com.unity.cinemachine/package.json +++ b/com.unity.cinemachine/package.json @@ -1,9 +1,8 @@ { "name": "com.unity.cinemachine", "displayName": "Cinemachine", - "version": "3.0.0-pre.8", + "version": "3.0.0-pre.9", "unity": "2022.3", - "unityRelease": "9f1", "description": "Smart camera tools for passionate creators. \n\nCinemachine 3.0 is a newer and better version of Cinemachine, but upgrading an existing project from 2.X will likely require some effort. If you're considering upgrading an older project, please see our upgrade guide in the user manual.", "keywords": [ "camera",