From 42f865a9709f8b860c1a4b245771ca9f4fcbc258 Mon Sep 17 00:00:00 2001 From: sim-bz Date: Wed, 21 Jan 2026 16:58:38 -0500 Subject: [PATCH 1/6] Added support for fast enter play mode to some static variables. --- .../Obsolete/CinemachineFreeLookEditor.cs | 91 +++++++++--------- .../CinemachineVirtualCameraEditor.cs | 95 +++++++++---------- .../Editor/Windows/CinemachineCorePrefs.cs | 6 ++ .../Behaviours/CinemachineDecollider.cs | 10 ++ .../Behaviours/CinemachineDeoccluder.cs | 8 ++ .../Runtime/Core/CameraState.cs | 2 +- .../Runtime/Core/CinemachineBlend.cs | 8 ++ .../Runtime/Core/CinemachineCore.cs | 39 ++++++-- .../Runtime/Debug/CinemachineDebug.cs | 8 ++ .../Runtime/Deprecated/CinemachineCollider.cs | 14 ++- .../CinemachineOrbitalTransposer.cs | 4 +- .../Runtime/ThirdParty/clipper.cs | 4 +- 12 files changed, 177 insertions(+), 112 deletions(-) diff --git a/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs b/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs index 4d90f3813..da4c38ab4 100644 --- a/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs +++ b/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs @@ -175,62 +175,59 @@ void UpdateRigEditor() /// /// Register with CinemachineFreeLook to create the pipeline in an undo-friendly manner /// - [InitializeOnLoad] - class CreateRigWithUndo + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() { - static CreateRigWithUndo() + CinemachineFreeLook.CreateRigOverride + = (CinemachineFreeLook vcam, string name, CinemachineVirtualCamera copyFrom) => { - CinemachineFreeLook.CreateRigOverride - = (CinemachineFreeLook vcam, string name, CinemachineVirtualCamera copyFrom) => + // Recycle the game object if it exists + GameObject go = null; + foreach (Transform child in vcam.transform) { - // Recycle the game object if it exists - GameObject go = null; - foreach (Transform child in vcam.transform) + if (child.gameObject.name == name) { - if (child.gameObject.name == name) - { - go = child.gameObject; - break; - } + go = child.gameObject; + break; } + } - CinemachineVirtualCamera rig = null; - if (go == null) - { - // Create a new rig - can't do it if prefab instance - if (PrefabUtility.IsPartOfAnyPrefab(vcam.gameObject)) - return null; - go = ObjectFactory.CreateGameObject(name); - Undo.RegisterCreatedObjectUndo(go, "created rig"); - Undo.SetTransformParent(go.transform, vcam.transform, "parenting pipeline"); - } + CinemachineVirtualCamera rig = null; + if (go == null) + { + // Create a new rig - can't do it if prefab instance + if (PrefabUtility.IsPartOfAnyPrefab(vcam.gameObject)) + return null; + go = ObjectFactory.CreateGameObject(name); + Undo.RegisterCreatedObjectUndo(go, "created rig"); + Undo.SetTransformParent(go.transform, vcam.transform, "parenting pipeline"); + } - // Create a new rig with default components - rig = Undo.AddComponent(go); - rig.CreatePipeline(copyFrom); - if (copyFrom != null) - ReflectionHelpers.CopyFields(copyFrom, rig); - else - { - // Defaults - go = rig.GetComponentOwner().gameObject; - Undo.AddComponent(go); - Undo.AddComponent(go); - rig.InvalidateComponentPipeline(); - } - return rig; - }; + // Create a new rig with default components + rig = Undo.AddComponent(go); + rig.CreatePipeline(copyFrom); + if (copyFrom != null) + ReflectionHelpers.CopyFields(copyFrom, rig); + else + { + // Defaults + go = rig.GetComponentOwner().gameObject; + Undo.AddComponent(go); + Undo.AddComponent(go); + rig.InvalidateComponentPipeline(); + } + return rig; + }; - CinemachineFreeLook.DestroyRigOverride = (GameObject rig) => + CinemachineFreeLook.DestroyRigOverride = (GameObject rig) => + { + var vcam = rig.GetComponent(); + if (vcam != null) { - var vcam = rig.GetComponent(); - if (vcam != null) - { - vcam.DestroyPipeline(); - Undo.DestroyObjectImmediate(vcam); - } - }; - } + vcam.DestroyPipeline(); + Undo.DestroyObjectImmediate(vcam); + } + }; } } } diff --git a/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs b/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs index b59f6f4a2..a68a76eec 100644 --- a/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs +++ b/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs @@ -165,63 +165,60 @@ void ResetTargetOnUndo() /// /// Register with CinemachineVirtualCamera to create the pipeline in an undo-friendly manner /// - [InitializeOnLoad] - class CreatePipelineWithUndo + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() { - static CreatePipelineWithUndo() + CinemachineVirtualCamera.CreatePipelineOverride = + (CinemachineVirtualCamera vcam, string name, CinemachineComponentBase[] copyFrom) => { - CinemachineVirtualCamera.CreatePipelineOverride = - (CinemachineVirtualCamera vcam, string name, CinemachineComponentBase[] copyFrom) => + // Recycle existing pipeline child (if any) + GameObject go = null; + foreach (Transform child in vcam.transform) { - // Recycle existing pipeline child (if any) - GameObject go = null; - foreach (Transform child in vcam.transform) + if (child.GetComponent() != null) { - if (child.GetComponent() != null) - { - go = child.gameObject; - break; - } - } - if (go == null) - { - // Create a new pipeline - can't do it if prefab instance - if (PrefabUtility.IsPartOfAnyPrefab(vcam.gameObject)) - return null; - go = ObjectFactory.CreateGameObject(name); - Undo.RegisterCreatedObjectUndo(go, "created pipeline"); - Undo.SetTransformParent(go.transform, vcam.transform, "parenting pipeline"); - Undo.AddComponent(go); + go = child.gameObject; + break; } - - var oldStuff = go.GetComponents(); - foreach (var c in oldStuff) - Undo.DestroyObjectImmediate(c); - - // If copying, transfer the components - if (copyFrom != null) + } + if (go == null) + { + // Create a new pipeline - can't do it if prefab instance + if (PrefabUtility.IsPartOfAnyPrefab(vcam.gameObject)) + return null; + go = ObjectFactory.CreateGameObject(name); + Undo.RegisterCreatedObjectUndo(go, "created pipeline"); + Undo.SetTransformParent(go.transform, vcam.transform, "parenting pipeline"); + Undo.AddComponent(go); + } + + var oldStuff = go.GetComponents(); + foreach (var c in oldStuff) + Undo.DestroyObjectImmediate(c); + + // If copying, transfer the components + if (copyFrom != null) + { + foreach (Component c in copyFrom) { - foreach (Component c in copyFrom) - { - Component copy = Undo.AddComponent(go, c.GetType()); - Undo.RecordObject(copy, "copying pipeline"); - ReflectionHelpers.CopyFields(c, copy); - } + Component copy = Undo.AddComponent(go, c.GetType()); + Undo.RecordObject(copy, "copying pipeline"); + ReflectionHelpers.CopyFields(c, copy); } - return go.transform; - }; + } + return go.transform; + }; - CinemachineVirtualCamera.DestroyPipelineOverride = (GameObject pipeline) => - { - var oldStuff = pipeline.GetComponents(); - foreach (var c in oldStuff) - Undo.DestroyObjectImmediate(c); - // Cannot create or destroy child objects if prefab. - // Just leave it there in that case, it will get discovered and recycled. - if (!PrefabUtility.IsPartOfAnyPrefab(pipeline)) - Undo.DestroyObjectImmediate(pipeline); - }; - } + CinemachineVirtualCamera.DestroyPipelineOverride = (GameObject pipeline) => + { + var oldStuff = pipeline.GetComponents(); + foreach (var c in oldStuff) + Undo.DestroyObjectImmediate(c); + // Cannot create or destroy child objects if prefab. + // Just leave it there in that case, it will get discovered and recycled. + if (!PrefabUtility.IsPartOfAnyPrefab(pipeline)) + Undo.DestroyObjectImmediate(pipeline); + }; } } } diff --git a/com.unity.cinemachine/Editor/Windows/CinemachineCorePrefs.cs b/com.unity.cinemachine/Editor/Windows/CinemachineCorePrefs.cs index d3ae40184..e5bb8ff9f 100644 --- a/com.unity.cinemachine/Editor/Windows/CinemachineCorePrefs.cs +++ b/com.unity.cinemachine/Editor/Windows/CinemachineCorePrefs.cs @@ -21,6 +21,12 @@ protected override void WritePrefs(bool value) CinemachineDebug.GameViewGuidesEnabled = value; } } + + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + CinemachineDebug.GameViewGuidesEnabled = ShowInGameGuides.Value; + } static CinemachineSettings.BoolItem s_SettingsFoldedOut = new("CNMCN_Core_Folded", true); diff --git a/com.unity.cinemachine/Runtime/Behaviours/CinemachineDecollider.cs b/com.unity.cinemachine/Runtime/Behaviours/CinemachineDecollider.cs index 74e6c9038..393bb558c 100644 --- a/com.unity.cinemachine/Runtime/Behaviours/CinemachineDecollider.cs +++ b/com.unity.cinemachine/Runtime/Behaviours/CinemachineDecollider.cs @@ -110,6 +110,16 @@ public struct TerrainSettings static float[] s_ColliderDistanceBuffer = new float[kColliderBufferSize]; static int[] s_ColliderOrderBuffer = new int[kColliderBufferSize]; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + Array.Fill(s_ColliderBuffer, null); + Array.Fill(s_ColliderDistanceBuffer, 0f); + Array.Fill(s_ColliderOrderBuffer, 0); + } +#endif + // Farthest stuff comes first static readonly IComparer s_ColliderBufferSorter = Comparer.Create((a, b) => { diff --git a/com.unity.cinemachine/Runtime/Behaviours/CinemachineDeoccluder.cs b/com.unity.cinemachine/Runtime/Behaviours/CinemachineDeoccluder.cs index eff71cd37..6895edb6a 100644 --- a/com.unity.cinemachine/Runtime/Behaviours/CinemachineDeoccluder.cs +++ b/com.unity.cinemachine/Runtime/Behaviours/CinemachineDeoccluder.cs @@ -827,6 +827,14 @@ static float ClampRayToBounds(Ray ray, float distance, Bounds bounds) static Collider[] s_ColliderBuffer = new Collider[5]; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + Array.Fill(s_ColliderBuffer, null); + } +#endif + Vector3 RespectCameraRadius(Vector3 cameraPos, Vector3 lookAtPos) { var result = Vector3.zero; diff --git a/com.unity.cinemachine/Runtime/Core/CameraState.cs b/com.unity.cinemachine/Runtime/Core/CameraState.cs index 9463f85ce..5e986915a 100644 --- a/com.unity.cinemachine/Runtime/Core/CameraState.cs +++ b/com.unity.cinemachine/Runtime/Core/CameraState.cs @@ -39,7 +39,7 @@ public struct CameraState /// /// This constant represents "no point in space" or "no direction". /// - public static Vector3 kNoPoint = new Vector3(float.NaN, float.NaN, float.NaN); + public static readonly Vector3 kNoPoint = new Vector3(float.NaN, float.NaN, float.NaN); /// /// Raw (un-corrected) world space position of this camera diff --git a/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs b/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs index 4f600e6b4..94b0dcfb9 100644 --- a/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs +++ b/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs @@ -266,6 +266,14 @@ void CreateStandardCurves() s_StandardCurves[(int)Styles.Linear] = AnimationCurve.Linear(0f, 0f, 1, 1f); } +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + s_StandardCurves = null; + } +#endif + /// /// A normalized AnimationCurve specifying the interpolation curve /// for this camera blend. Y-axis values must be in range [0,1] (internally clamped diff --git a/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs b/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs index 6bc7eaae3..e4c0ba22f 100644 --- a/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs +++ b/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs @@ -102,20 +102,24 @@ public enum BlendHints /// The value of the axis. public delegate float AxisInputDelegate(string axisName); - /// Delegate for overriding Unity's default input system. - /// If you set this, then your delegate will be called instead of - /// System.Input.GetAxis(axisName) whenever in-game user input is needed. #if ENABLE_LEGACY_INPUT_MANAGER - public static AxisInputDelegate GetInputAxis = UnityEngine.Input.GetAxis; + static readonly AxisInputDelegate DefaultGetInputAxis = UnityEngine.Input.GetAxis; #else - public static AxisInputDelegate GetInputAxis = delegate { return 0; }; + static readonly AxisInputDelegate s_DefaultGetInputAxis = delegate { return 0; }; #endif + + /// Delegate for overriding Unity's default input system. + /// If you set this, then your delegate will be called instead of + /// System.Input.GetAxis(axisName) whenever in-game user input is needed. + public static AxisInputDelegate GetInputAxis = s_DefaultGetInputAxis; + const float k_DefaultUniformDeltaTimeOverride = -1; + /// /// If non-negative, cinemachine will update with this uniform delta time. /// Usage is for timelines in manual update mode. /// - public static float UniformDeltaTimeOverride = -1; + public static float UniformDeltaTimeOverride = k_DefaultUniformDeltaTimeOverride; /// /// Replacement for Time.deltaTime, taking UniformDeltaTimeOverride into account. @@ -123,17 +127,21 @@ public enum BlendHints public static float DeltaTime => UniformDeltaTimeOverride >= 0 ? UniformDeltaTimeOverride : Time.deltaTime; + const float k_DefaultCurrentTimeOverride = -1; + /// /// If non-negative, cinemachine will use this value whenever it wants current game time. /// Usage is for master timelines in manual update mode, for deterministic behaviour. /// - public static float CurrentTimeOverride = -1; + public static float CurrentTimeOverride = k_DefaultCurrentTimeOverride; /// /// Replacement for Time.time, taking CurrentTimeTimeOverride into account. /// public static float CurrentTime => CurrentTimeOverride >= 0 ? CurrentTimeOverride : Time.time; + const int k_DefaultCurrentUpdateFrame = 0; + /// /// The current frame /// By default this is Time.frameCount. If you are using ManualUpdate with a custom update frame, @@ -261,6 +269,21 @@ public static ICinemachineCamera SoloCamera } static ICinemachineCamera s_SoloCamera; + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + UniformDeltaTimeOverride = k_DefaultUniformDeltaTimeOverride; + CurrentTimeOverride = k_DefaultCurrentTimeOverride; + CurrentUpdateFrame = k_DefaultCurrentUpdateFrame; + GetInputAxis = s_DefaultGetInputAxis; + s_SoloCamera = null; + } +#endif + + + /// /// Is this virtual camera currently actively controlling any Camera? /// @@ -369,4 +392,4 @@ public static void ResetCameraState() CinemachineBrain.GetActiveBrain(i).ResetState(); } } -} +} \ No newline at end of file diff --git a/com.unity.cinemachine/Runtime/Debug/CinemachineDebug.cs b/com.unity.cinemachine/Runtime/Debug/CinemachineDebug.cs index ad2b1e7b5..654c712db 100644 --- a/com.unity.cinemachine/Runtime/Debug/CinemachineDebug.cs +++ b/com.unity.cinemachine/Runtime/Debug/CinemachineDebug.cs @@ -148,5 +148,13 @@ public static void ReturnToPool(StringBuilder sb) s_AvailableStringBuilders ??= new List(); s_AvailableStringBuilders.Add(sb); } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + s_AvailableStringBuilders = null; + } +#endif } } diff --git a/com.unity.cinemachine/Runtime/Deprecated/CinemachineCollider.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineCollider.cs index a732f8588..676aeafe7 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineCollider.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineCollider.cs @@ -126,7 +126,17 @@ public enum ResolutionStrategy [Tooltip("If greater than zero, a higher score will be given to shots when the target is closer to this distance. " + "Set this to zero to disable this feature.")] public float m_OptimalTargetDistance; + + static Collider[] s_ColliderBuffer = new Collider[5]; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + Array.Fill(s_ColliderBuffer, null); + } +#endif + /// See whether an object is blocking the camera's view of the target /// The virtual camera in question. This might be different from the /// virtual camera that owns the collider, in the event that the camera has children @@ -659,9 +669,7 @@ static float ClampRayToBounds(Ray ray, float distance, Bounds bounds) } return distance; } - - static Collider[] s_ColliderBuffer = new Collider[5]; - + Vector3 RespectCameraRadius(Vector3 cameraPos, Vector3 lookAtPos) { Vector3 result = Vector3.zero; diff --git a/com.unity.cinemachine/Runtime/Deprecated/CinemachineOrbitalTransposer.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineOrbitalTransposer.cs index 6c957c533..1b0851244 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineOrbitalTransposer.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineOrbitalTransposer.cs @@ -49,8 +49,8 @@ void ClearHistory() mHeadingSum = Vector3.zero; } - static float mDecayExponent; - static float Decay(float time) { return Mathf.Exp(time * mDecayExponent); } + float mDecayExponent; + float Decay(float time) { return Mathf.Exp(time * mDecayExponent); } /// Add a new velocity frame. This should be called once per frame, /// unless the velocity is zero diff --git a/com.unity.cinemachine/Runtime/ThirdParty/clipper.cs b/com.unity.cinemachine/Runtime/ThirdParty/clipper.cs index 3c0f9ab71..00a47f385 100644 --- a/com.unity.cinemachine/Runtime/ThirdParty/clipper.cs +++ b/com.unity.cinemachine/Runtime/ThirdParty/clipper.cs @@ -31,10 +31,10 @@ namespace Unity.Cinemachine static class Clipper { - public static Rect64 MaxInvalidRect64 = new Rect64( + public static readonly Rect64 MaxInvalidRect64 = new Rect64( long.MaxValue, long.MaxValue, long.MinValue, long.MinValue); - public static RectD MaxInvalidRectD = new RectD( + public static readonly RectD MaxInvalidRectD = new RectD( double.MaxValue, -double.MaxValue, -double.MaxValue, -double.MaxValue); public static Paths64 Intersect(Paths64 subject, Paths64 clip, FillRule fillRule) From 285963317b4f390ac82715e2b4ee7f201403901d Mon Sep 17 00:00:00 2001 From: sim-bz Date: Fri, 30 Jan 2026 13:25:36 -0500 Subject: [PATCH 2/6] Fixed typo.. --- com.unity.cinemachine/Runtime/Core/CinemachineCore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs b/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs index e4c0ba22f..bc11397fb 100644 --- a/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs +++ b/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs @@ -103,7 +103,7 @@ public enum BlendHints public delegate float AxisInputDelegate(string axisName); #if ENABLE_LEGACY_INPUT_MANAGER - static readonly AxisInputDelegate DefaultGetInputAxis = UnityEngine.Input.GetAxis; + static readonly AxisInputDelegate s_DefaultGetInputAxis = UnityEngine.Input.GetAxis; #else static readonly AxisInputDelegate s_DefaultGetInputAxis = delegate { return 0; }; #endif From d419851b8cedf1a784242a6c52fbea907463e6bb Mon Sep 17 00:00:00 2001 From: sim-bz Date: Thu, 12 Feb 2026 15:29:50 -0500 Subject: [PATCH 3/6] Added more support for ResetStaticsOnLoad. --- .../Behaviours/CinemachineStoryboard.cs | 6 +++ .../Runtime/Core/CameraUpdateManager.cs | 13 ++++++ .../Runtime/Core/CinemachineBlend.cs | 17 ++++---- .../Runtime/Core/CinemachineCore.cs | 40 +++++++++++-------- .../Runtime/Core/Predictor.cs | 15 +++++++ .../Runtime/Core/RuntimeUtility.cs | 14 +++++++ .../Runtime/Core/TargetPositionCache.cs | 14 +++++++ .../Runtime/Core/UpdateTracker.cs | 9 +++++ .../Runtime/Debug/CinemachineDebug.cs | 4 +- .../Runtime/Deprecated/CinemachineFreeLook.cs | 9 +++++ .../Deprecated/CinemachineVirtualCamera.cs | 9 +++++ .../Helpers/CinemachineInputAxisController.cs | 8 ++++ .../Impulse/CinemachineImpulseDefinition.cs | 9 +++++ .../Impulse/CinemachineImpulseManager.cs | 8 ++++ .../CinemachineVolumeSettings.cs | 12 +++++- .../Timeline/CinemachinePlayableMixer.cs | 8 ++++ 16 files changed, 169 insertions(+), 26 deletions(-) diff --git a/com.unity.cinemachine/Runtime/Behaviours/CinemachineStoryboard.cs b/com.unity.cinemachine/Runtime/Behaviours/CinemachineStoryboard.cs index e3cfb1012..e223a23cb 100644 --- a/com.unity.cinemachine/Runtime/Behaviours/CinemachineStoryboard.cs +++ b/com.unity.cinemachine/Runtime/Behaviours/CinemachineStoryboard.cs @@ -442,6 +442,12 @@ public static void AddCanvas(UnityEngine.Object canvas, UnityEngine.Object owner s_CanvasesAndTheirOwners.Add(canvas, owner); } } + + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + s_StoryboardGlobalMute = false; + } #endif } } diff --git a/com.unity.cinemachine/Runtime/Core/CameraUpdateManager.cs b/com.unity.cinemachine/Runtime/Core/CameraUpdateManager.cs index 341474e49..73890c36c 100644 --- a/com.unity.cinemachine/Runtime/Core/CameraUpdateManager.cs +++ b/com.unity.cinemachine/Runtime/Core/CameraUpdateManager.cs @@ -222,5 +222,18 @@ public static UpdateTracker.UpdateClock GetVcamUpdateStatus(CinemachineVirtualCa return UpdateTracker.UpdateClock.Late; return status.lastUpdateMode; } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + s_RoundRobinIndex = 0; + s_RoundRobinSubIndex = 0; + s_LastFixedUpdateContext = null; + s_LastUpdateTime = 0f; + s_FixedFrameCount = 0; + s_CurrentUpdateFilter = default; + } +#endif } } diff --git a/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs b/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs index 94b0dcfb9..ee74a12d3 100644 --- a/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs +++ b/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs @@ -232,6 +232,15 @@ public CinemachineBlendDefinition(Styles style, float time) public AnimationCurve CustomCurve; static AnimationCurve[] s_StandardCurves; + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + s_StandardCurves = null; + } +#endif + void CreateStandardCurves() { s_StandardCurves = new AnimationCurve[(int)Styles.Custom]; @@ -265,14 +274,6 @@ void CreateStandardCurves() s_StandardCurves[(int)Styles.Linear] = AnimationCurve.Linear(0f, 0f, 1, 1f); } - -#if UNITY_EDITOR - [RuntimeInitializeOnLoadMethod] - private static void ResetStaticsOnLoad() - { - s_StandardCurves = null; - } -#endif /// /// A normalized AnimationCurve specifying the interpolation curve diff --git a/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs b/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs index bc11397fb..8c9b2af3a 100644 --- a/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs +++ b/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs @@ -28,12 +28,14 @@ public static class CinemachineCore /// public const string kPackageRoot = "Packages/com.unity.cinemachine"; + const float k_DefaultCurrentUnscaledTimeTimeOverride = -1; + /// /// Unit-test support: /// If non-negative, cinemachine will use this value whenever it wants current unscaled game time. /// Usage is for InputAxis in manual update mode, for deterministic behaviour. /// - internal static float CurrentUnscaledTimeTimeOverride = -1; + internal static float CurrentUnscaledTimeTimeOverride = k_DefaultCurrentUnscaledTimeTimeOverride; /// /// Unit-test support: @@ -269,21 +271,6 @@ public static ICinemachineCamera SoloCamera } static ICinemachineCamera s_SoloCamera; - -#if UNITY_EDITOR - [RuntimeInitializeOnLoadMethod] - private static void ResetStaticsOnLoad() - { - UniformDeltaTimeOverride = k_DefaultUniformDeltaTimeOverride; - CurrentTimeOverride = k_DefaultCurrentTimeOverride; - CurrentUpdateFrame = k_DefaultCurrentUpdateFrame; - GetInputAxis = s_DefaultGetInputAxis; - s_SoloCamera = null; - } -#endif - - - /// /// Is this virtual camera currently actively controlling any Camera? /// @@ -391,5 +378,26 @@ public static void ResetCameraState() for (int i = 0; i < numBrains; ++i) CinemachineBrain.GetActiveBrain(i).ResetState(); } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + CurrentUnscaledTimeTimeOverride = k_DefaultCurrentUnscaledTimeTimeOverride; + UnitTestMode = false; + UniformDeltaTimeOverride = k_DefaultUniformDeltaTimeOverride; + CurrentTimeOverride = k_DefaultCurrentTimeOverride; + CurrentUpdateFrame = k_DefaultCurrentUpdateFrame; + GetInputAxis = s_DefaultGetInputAxis; + GetBlendOverride = null; + GetCustomBlender = null; + //CameraUpdatedEvent = new(); + //CameraActivatedEvent = new(); + CameraDeactivatedEvent = new(); + BlendCreatedEvent = new(); + BlendFinishedEvent = new(); + s_SoloCamera = null; + } +#endif } } \ No newline at end of file diff --git a/com.unity.cinemachine/Runtime/Core/Predictor.cs b/com.unity.cinemachine/Runtime/Core/Predictor.cs index 9be08e149..be6f8fffb 100644 --- a/com.unity.cinemachine/Runtime/Core/Predictor.cs +++ b/com.unity.cinemachine/Runtime/Core/Predictor.cs @@ -1,3 +1,4 @@ +using System; using UnityEngine; using UnityEngine.SceneManagement; @@ -295,6 +296,20 @@ internal static void SetDampTimeScale(float fps) // Valid only for kSubframeTime = 1.0f / 1024.0f DampTimeScale = 2.0f - 1.81e-3f * fps + 7.9e-07f * fps * fps; } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + Array.Fill(s_Buffer, 0f); + s_NumItems = 0; + s_Head = 0; + s_Sum = 0; + + FPS = 0f; + DampTimeScale = 0f; + } +#endif } } } diff --git a/com.unity.cinemachine/Runtime/Core/RuntimeUtility.cs b/com.unity.cinemachine/Runtime/Core/RuntimeUtility.cs index fc8ecc7d3..f02064253 100644 --- a/com.unity.cinemachine/Runtime/Core/RuntimeUtility.cs +++ b/com.unity.cinemachine/Runtime/Core/RuntimeUtility.cs @@ -1,3 +1,4 @@ +using System; using UnityEngine; namespace Unity.Cinemachine @@ -222,8 +223,21 @@ public static void DestroyScratchCollider() s_ScratchCollider = null; } } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + Array.Fill(s_HitBuffer, default); + Array.Fill(s_PenetrationIndexBuffer, 0); + s_ScratchCollider = null; + s_ScratchColliderGameObject = null; + s_ScratchColliderRefCount = 0; + } #endif +#endif // CINEMACHINE_PHYSICS + /// /// Normalize a curve so that its X and Y axes range from 0 to 1 /// diff --git a/com.unity.cinemachine/Runtime/Core/TargetPositionCache.cs b/com.unity.cinemachine/Runtime/Core/TargetPositionCache.cs index 5f610fd46..a2af6ec88 100644 --- a/com.unity.cinemachine/Runtime/Core/TargetPositionCache.cs +++ b/com.unity.cinemachine/Runtime/Core/TargetPositionCache.cs @@ -308,5 +308,19 @@ public static Quaternion GetTargetRotation(Transform target) } return entry.Curve.Evaluate(CurrentTime).Rot; } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + UseCache = false; + m_CacheMode = Mode.Disabled; + CurrentTime = 0f; + CurrentFrame = 0; + IsCameraCut = false; + m_Cache = null; + m_CacheTimeRange = default; + } +#endif } } diff --git a/com.unity.cinemachine/Runtime/Core/UpdateTracker.cs b/com.unity.cinemachine/Runtime/Core/UpdateTracker.cs index 8f24d262f..bc1bf2b9c 100644 --- a/com.unity.cinemachine/Runtime/Core/UpdateTracker.cs +++ b/com.unity.cinemachine/Runtime/Core/UpdateTracker.cs @@ -129,5 +129,14 @@ public static void ForgetContext(object context) if (s_LastUpdateContext == context) s_LastUpdateContext = null; } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + s_ToDelete.Clear(); + s_LastUpdateContext = null; + } +#endif } } diff --git a/com.unity.cinemachine/Runtime/Debug/CinemachineDebug.cs b/com.unity.cinemachine/Runtime/Debug/CinemachineDebug.cs index 654c712db..c3de36d9b 100644 --- a/com.unity.cinemachine/Runtime/Debug/CinemachineDebug.cs +++ b/com.unity.cinemachine/Runtime/Debug/CinemachineDebug.cs @@ -126,7 +126,7 @@ static void PositionWithinCameraView(VisualElement viewportContainer, Camera cam /// /// Tracks CinemachineCorePrefs.ShowInGameGuides.Value, so it can be accessed at runtime /// - public static bool GameViewGuidesEnabled; + public static bool GameViewGuidesEnabled = false; /// Get a pre-allocated StringBuilder from the pool /// The pre-allocated StringBuilder from the pool. @@ -154,6 +154,8 @@ public static void ReturnToPool(StringBuilder sb) private static void ResetStaticsOnLoad() { s_AvailableStringBuilders = null; + OnGUIHandlers = null; + GameViewGuidesEnabled = false; } #endif } diff --git a/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs index 83ae3133f..7232fa262 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs @@ -941,6 +941,15 @@ void UpdateCachedSpline() m_CachedTension = m_SplineCurvature; } } + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + CreateRigOverride = null; + DestroyRigOverride = null; + } +#endif } } #endif diff --git a/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs index e25e8f5b7..74a05088f 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs @@ -208,6 +208,15 @@ protected void OnValidate() m_Lens.Validate(); } +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + CreatePipelineOverride = null; + DestroyPipelineOverride + } +#endif + void OnTransformChildrenChanged() { InvalidateComponentPipeline(); diff --git a/com.unity.cinemachine/Runtime/Helpers/CinemachineInputAxisController.cs b/com.unity.cinemachine/Runtime/Helpers/CinemachineInputAxisController.cs index e6af44ca3..ba04553c6 100644 --- a/com.unity.cinemachine/Runtime/Helpers/CinemachineInputAxisController.cs +++ b/com.unity.cinemachine/Runtime/Helpers/CinemachineInputAxisController.cs @@ -48,6 +48,14 @@ internal delegate void SetControlDefaultsForAxis( in IInputAxisOwner.AxisDescriptor axis, ref Controller controller); internal static SetControlDefaultsForAxis SetControlDefaults; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + SetControlDefaults = null; + } +#endif + #if CINEMACHINE_UNITY_INPUTSYSTEM /// /// CinemachineInputAxisController.Reader can only handle float or Vector2 InputAction types. diff --git a/com.unity.cinemachine/Runtime/Impulse/CinemachineImpulseDefinition.cs b/com.unity.cinemachine/Runtime/Impulse/CinemachineImpulseDefinition.cs index 2f6706987..3f1f02578 100644 --- a/com.unity.cinemachine/Runtime/Impulse/CinemachineImpulseDefinition.cs +++ b/com.unity.cinemachine/Runtime/Impulse/CinemachineImpulseDefinition.cs @@ -222,6 +222,15 @@ public void OnValidate() } static AnimationCurve[] s_StandardShapes; + +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + s_StandardShapes = null; + } +#endif + static void CreateStandardShapes() { int max = 0; diff --git a/com.unity.cinemachine/Runtime/Impulse/CinemachineImpulseManager.cs b/com.unity.cinemachine/Runtime/Impulse/CinemachineImpulseManager.cs index dc01f1daa..a54473355 100644 --- a/com.unity.cinemachine/Runtime/Impulse/CinemachineImpulseManager.cs +++ b/com.unity.cinemachine/Runtime/Impulse/CinemachineImpulseManager.cs @@ -31,12 +31,20 @@ public static CinemachineImpulseManager Instance } } +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + static void ResetStaticsOnLoad() + { + s_Instance = null; + } +#else [RuntimeInitializeOnLoadMethod] static void InitializeModule() { if (s_Instance != null) s_Instance.Clear(); } +#endif const float Epsilon = UnityVectorExtensions.Epsilon; diff --git a/com.unity.cinemachine/Runtime/PostProcessing/CinemachineVolumeSettings.cs b/com.unity.cinemachine/Runtime/PostProcessing/CinemachineVolumeSettings.cs index 5994cc795..b12652bc6 100644 --- a/com.unity.cinemachine/Runtime/PostProcessing/CinemachineVolumeSettings.cs +++ b/com.unity.cinemachine/Runtime/PostProcessing/CinemachineVolumeSettings.cs @@ -31,12 +31,14 @@ namespace Unity.Cinemachine [HelpURL(Documentation.BaseURL + "manual/CinemachineVolumeSettings.html")] public class CinemachineVolumeSettings : CinemachineExtension { + private const float k_DefaultVolumePriority = 1000f; + /// /// This is the priority for the vcam's PostProcessing volumes. It's set to a high /// number in order to ensure that it overrides other volumes for the active vcam. /// You can change this value if necessary to work with other systems. /// - public static float s_VolumePriority = 1000f; + public static float s_VolumePriority = k_DefaultVolumePriority; /// /// This is the weight that the PostProcessing profile will have when the camera is fully active. @@ -358,6 +360,14 @@ static void InitializeModule() CinemachineCore.CameraActivatedEvent.RemoveListener(OnCameraCut); CinemachineCore.CameraActivatedEvent.AddListener(OnCameraCut); } + + [RuntimeInitializeOnLoadMethod] + static void ResetStaticsOnLoad() + { + s_VolumePriority = k_DefaultVolumePriority; + sVolumes = new(); + } + } } #endif diff --git a/com.unity.cinemachine/Runtime/Timeline/CinemachinePlayableMixer.cs b/com.unity.cinemachine/Runtime/Timeline/CinemachinePlayableMixer.cs index e0d51df82..41f5359ee 100644 --- a/com.unity.cinemachine/Runtime/Timeline/CinemachinePlayableMixer.cs +++ b/com.unity.cinemachine/Runtime/Timeline/CinemachinePlayableMixer.cs @@ -14,6 +14,14 @@ internal sealed class CinemachinePlayableMixer : PlayableBehaviour public delegate PlayableDirector MasterDirectorDelegate(); public static MasterDirectorDelegate GetMasterPlayableDirector; +#if UNITY_EDITOR + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + GetMasterPlayableDirector = null; + } +#endif + // The brain that this track controls ICameraOverrideStack m_BrainOverrideStack; int m_BrainOverrideId = -1; From aa8e5b2051f7de2bba2ea8a597ab1839efbbfa33 Mon Sep 17 00:00:00 2001 From: sim-bz Date: Thu, 12 Feb 2026 15:53:42 -0500 Subject: [PATCH 4/6] Cleanup and more exceptions. --- .../Obsolete/CinemachineFreeLookEditor.cs | 103 ++++++++++-------- .../CinemachineVirtualCameraEditor.cs | 101 +++++++++-------- .../Runtime/Core/CinemachineBlend.cs | 2 +- .../Runtime/Deprecated/CinemachineFreeLook.cs | 4 +- .../Deprecated/CinemachineVirtualCamera.cs | 6 +- 5 files changed, 114 insertions(+), 102 deletions(-) diff --git a/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs b/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs index da4c38ab4..8899aee61 100644 --- a/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs +++ b/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs @@ -34,6 +34,8 @@ protected override void OnEnable() { base.OnEnable(); Target.UpdateInputAxisProvider(); + + CinemachineFreeLook.CreateRigOverride += CreateRigOverride; } protected override void OnDisable() @@ -172,62 +174,67 @@ void UpdateRigEditor() } } - /// - /// Register with CinemachineFreeLook to create the pipeline in an undo-friendly manner - /// - [RuntimeInitializeOnLoadMethod] - private static void ResetStaticsOnLoad() + static CinemachineVirtualCamera CreateRigOverride(CinemachineFreeLook vcam, string name, CinemachineVirtualCamera copyFrom) { - CinemachineFreeLook.CreateRigOverride - = (CinemachineFreeLook vcam, string name, CinemachineVirtualCamera copyFrom) => + // Recycle the game object if it exists + GameObject go = null; + foreach (Transform child in vcam.transform) { - // Recycle the game object if it exists - GameObject go = null; - foreach (Transform child in vcam.transform) + if (child.gameObject.name == name) { - if (child.gameObject.name == name) - { - go = child.gameObject; - break; - } + go = child.gameObject; + break; } + } - CinemachineVirtualCamera rig = null; - if (go == null) - { - // Create a new rig - can't do it if prefab instance - if (PrefabUtility.IsPartOfAnyPrefab(vcam.gameObject)) - return null; - go = ObjectFactory.CreateGameObject(name); - Undo.RegisterCreatedObjectUndo(go, "created rig"); - Undo.SetTransformParent(go.transform, vcam.transform, "parenting pipeline"); - } + CinemachineVirtualCamera rig = null; + if (go == null) + { + // Create a new rig - can't do it if prefab instance + if (PrefabUtility.IsPartOfAnyPrefab(vcam.gameObject)) + return null; + go = ObjectFactory.CreateGameObject(name); + Undo.RegisterCreatedObjectUndo(go, "created rig"); + Undo.SetTransformParent(go.transform, vcam.transform, "parenting pipeline"); + } - // Create a new rig with default components - rig = Undo.AddComponent(go); - rig.CreatePipeline(copyFrom); - if (copyFrom != null) - ReflectionHelpers.CopyFields(copyFrom, rig); - else - { - // Defaults - go = rig.GetComponentOwner().gameObject; - Undo.AddComponent(go); - Undo.AddComponent(go); - rig.InvalidateComponentPipeline(); - } - return rig; - }; + // Create a new rig with default components + rig = Undo.AddComponent(go); + rig.CreatePipeline(copyFrom); + if (copyFrom != null) + ReflectionHelpers.CopyFields(copyFrom, rig); + else + { + // Defaults + go = rig.GetComponentOwner().gameObject; + Undo.AddComponent(go); + Undo.AddComponent(go); + rig.InvalidateComponentPipeline(); + } + return rig; + } - CinemachineFreeLook.DestroyRigOverride = (GameObject rig) => + static void DestroyRigOverride(GameObject rig) + { + var vcam = rig.GetComponent(); + if (vcam != null) { - var vcam = rig.GetComponent(); - if (vcam != null) - { - vcam.DestroyPipeline(); - Undo.DestroyObjectImmediate(vcam); - } - }; + vcam.DestroyPipeline(); + Undo.DestroyObjectImmediate(vcam); + } + } + + [UnityEditor.InitializeOnLoad] + class EditorInitialize { static EditorInitialize() { ResetStaticsOnLoad(); } } + + /// + /// Register with CinemachineFreeLook to create the pipeline in an undo-friendly manner + /// + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + CinemachineFreeLook.CreateRigOverride = CreateRigOverride; + CinemachineFreeLook.DestroyRigOverride = DestroyRigOverride; } } } diff --git a/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs b/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs index a68a76eec..2fe983a15 100644 --- a/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs +++ b/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs @@ -162,63 +162,68 @@ void ResetTargetOnUndo() (targets[i] as CinemachineVirtualCamera).InvalidateComponentPipeline(); } - /// - /// Register with CinemachineVirtualCamera to create the pipeline in an undo-friendly manner - /// - [RuntimeInitializeOnLoadMethod] - private static void ResetStaticsOnLoad() + static Transform CreatePipelineOverride(CinemachineVirtualCamera vcam, string name, CinemachineComponentBase[] copyFrom) { - CinemachineVirtualCamera.CreatePipelineOverride = - (CinemachineVirtualCamera vcam, string name, CinemachineComponentBase[] copyFrom) => + // Recycle existing pipeline child (if any) + GameObject go = null; + foreach (Transform child in vcam.transform) { - // Recycle existing pipeline child (if any) - GameObject go = null; - foreach (Transform child in vcam.transform) - { - if (child.GetComponent() != null) - { - go = child.gameObject; - break; - } - } - if (go == null) + if (child.GetComponent() != null) { - // Create a new pipeline - can't do it if prefab instance - if (PrefabUtility.IsPartOfAnyPrefab(vcam.gameObject)) - return null; - go = ObjectFactory.CreateGameObject(name); - Undo.RegisterCreatedObjectUndo(go, "created pipeline"); - Undo.SetTransformParent(go.transform, vcam.transform, "parenting pipeline"); - Undo.AddComponent(go); + go = child.gameObject; + break; } + } + if (go == null) + { + // Create a new pipeline - can't do it if prefab instance + if (PrefabUtility.IsPartOfAnyPrefab(vcam.gameObject)) + return null; + go = ObjectFactory.CreateGameObject(name); + Undo.RegisterCreatedObjectUndo(go, "created pipeline"); + Undo.SetTransformParent(go.transform, vcam.transform, "parenting pipeline"); + Undo.AddComponent(go); + } - var oldStuff = go.GetComponents(); - foreach (var c in oldStuff) - Undo.DestroyObjectImmediate(c); + var oldStuff = go.GetComponents(); + foreach (var c in oldStuff) + Undo.DestroyObjectImmediate(c); - // If copying, transfer the components - if (copyFrom != null) + // If copying, transfer the components + if (copyFrom != null) + { + foreach (Component c in copyFrom) { - foreach (Component c in copyFrom) - { - Component copy = Undo.AddComponent(go, c.GetType()); - Undo.RecordObject(copy, "copying pipeline"); - ReflectionHelpers.CopyFields(c, copy); - } + Component copy = Undo.AddComponent(go, c.GetType()); + Undo.RecordObject(copy, "copying pipeline"); + ReflectionHelpers.CopyFields(c, copy); } - return go.transform; - }; + } + return go.transform; + } - CinemachineVirtualCamera.DestroyPipelineOverride = (GameObject pipeline) => - { - var oldStuff = pipeline.GetComponents(); - foreach (var c in oldStuff) - Undo.DestroyObjectImmediate(c); - // Cannot create or destroy child objects if prefab. - // Just leave it there in that case, it will get discovered and recycled. - if (!PrefabUtility.IsPartOfAnyPrefab(pipeline)) - Undo.DestroyObjectImmediate(pipeline); - }; + static void DestroyPipelineOverride(GameObject pipeline) + { + var oldStuff = pipeline.GetComponents(); + foreach (var c in oldStuff) + Undo.DestroyObjectImmediate(c); + // Cannot create or destroy child objects if prefab. + // Just leave it there in that case, it will get discovered and recycled. + if (!PrefabUtility.IsPartOfAnyPrefab(pipeline)) + Undo.DestroyObjectImmediate(pipeline); + } + + [UnityEditor.InitializeOnLoad] + class EditorInitialize { static EditorInitialize() { ResetStaticsOnLoad(); } } + + /// + /// Register with CinemachineVirtualCamera to create the pipeline in an undo-friendly manner + /// + [RuntimeInitializeOnLoadMethod] + private static void ResetStaticsOnLoad() + { + CinemachineVirtualCamera.CreatePipelineOverride = CreatePipelineOverride; + CinemachineVirtualCamera.DestroyPipelineOverride = DestroyPipelineOverride; } } } diff --git a/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs b/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs index ee74a12d3..cf63db4c1 100644 --- a/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs +++ b/com.unity.cinemachine/Runtime/Core/CinemachineBlend.cs @@ -274,7 +274,7 @@ void CreateStandardCurves() s_StandardCurves[(int)Styles.Linear] = AnimationCurve.Linear(0f, 0f, 1, 1f); } - + /// /// A normalized AnimationCurve specifying the interpolation curve /// for this camera blend. Y-axis values must be in range [0,1] (internally clamped diff --git a/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs index 7232fa262..8d0ecc96f 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs @@ -946,8 +946,8 @@ void UpdateCachedSpline() [RuntimeInitializeOnLoadMethod] private static void ResetStaticsOnLoad() { - CreateRigOverride = null; - DestroyRigOverride = null; + //CreateRigOverride = null; + //DestroyRigOverride = null; } #endif } diff --git a/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs index 74a05088f..6e98dd2bd 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs @@ -212,11 +212,11 @@ protected void OnValidate() [RuntimeInitializeOnLoadMethod] private static void ResetStaticsOnLoad() { - CreatePipelineOverride = null; - DestroyPipelineOverride + //CreatePipelineOverride = null; + //DestroyPipelineOverride = null; } #endif - + void OnTransformChildrenChanged() { InvalidateComponentPipeline(); From ba15796fbda8a928a66e05779ec64a1002ca37f7 Mon Sep 17 00:00:00 2001 From: sim-bz Date: Tue, 17 Feb 2026 10:51:13 -0500 Subject: [PATCH 5/6] Added pragma disabled UDR0001 for problematic static events. --- .../Editor/Obsolete/CinemachineFreeLookEditor.cs | 2 -- .../Runtime/Core/CinemachineCore.cs | 6 ++++-- com.unity.cinemachine/Runtime/Core/UpdateTracker.cs | 4 +--- .../Runtime/Deprecated/CinemachineFreeLook.cs | 13 ++++--------- .../Runtime/Deprecated/CinemachineVirtualCamera.cs | 13 ++++--------- 5 files changed, 13 insertions(+), 25 deletions(-) diff --git a/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs b/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs index 8899aee61..710c147b9 100644 --- a/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs +++ b/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs @@ -34,8 +34,6 @@ protected override void OnEnable() { base.OnEnable(); Target.UpdateInputAxisProvider(); - - CinemachineFreeLook.CreateRigOverride += CreateRigOverride; } protected override void OnDisable() diff --git a/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs b/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs index 8c9b2af3a..f8142b4c3 100644 --- a/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs +++ b/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs @@ -200,7 +200,9 @@ public class CameraEvent : UnityEvent {} public class BrainEvent : UnityEvent {} /// This event will fire after a brain updates its Camera +#pragma warning disable UDR0001 public static BrainEvent CameraUpdatedEvent = new (); +#pragma warning restore UDR0001 /// This is sent with BlendEvent public struct BlendEventParams @@ -217,7 +219,9 @@ public class BlendEvent : UnityEvent {} /// This event will fire when the current camera changes, /// at the start of a blend +#pragma warning disable UDR0001 public static ICinemachineCamera.ActivationEvent CameraActivatedEvent = new (); +#pragma warning restore UDR0001 /// This event will fire immediately after a camera that is /// live in some context stops being live. @@ -391,8 +395,6 @@ private static void ResetStaticsOnLoad() GetInputAxis = s_DefaultGetInputAxis; GetBlendOverride = null; GetCustomBlender = null; - //CameraUpdatedEvent = new(); - //CameraActivatedEvent = new(); CameraDeactivatedEvent = new(); BlendCreatedEvent = new(); BlendFinishedEvent = new(); diff --git a/com.unity.cinemachine/Runtime/Core/UpdateTracker.cs b/com.unity.cinemachine/Runtime/Core/UpdateTracker.cs index bc1bf2b9c..0456ac028 100644 --- a/com.unity.cinemachine/Runtime/Core/UpdateTracker.cs +++ b/com.unity.cinemachine/Runtime/Core/UpdateTracker.cs @@ -72,9 +72,6 @@ public void OnUpdate(int currentFrame, UpdateClock currentClock, Matrix4x4 pos) } static Dictionary s_UpdateStatus = new(); - [RuntimeInitializeOnLoadMethod] - static void InitializeModule() => s_UpdateStatus.Clear(); - static List s_ToDelete = new(); static void UpdateTargets(UpdateClock currentClock) { @@ -135,6 +132,7 @@ public static void ForgetContext(object context) private static void ResetStaticsOnLoad() { s_ToDelete.Clear(); + s_UpdateStatus.Clear(); s_LastUpdateContext = null; } #endif diff --git a/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs index 8d0ecc96f..8bdf9a639 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs @@ -557,7 +557,9 @@ void ChooseBestAngle(float x) /// This needs to be done by the editor to support Undo. /// The override must do exactly the same thing as the CreatePipeline method in this class. /// +#pragma warning disable UDR0001 public static CreateRigDelegate CreateRigOverride; +#pragma warning restore UDR0001 /// /// Override component pipeline creation. @@ -575,7 +577,9 @@ public delegate CinemachineVirtualCamera CreateRigDelegate( /// Override component pipeline destruction. /// This needs to be done by the editor to support Undo. /// +#pragma warning disable UDR0001 public static DestroyRigDelegate DestroyRigOverride; +#pragma warning restore UDR0001 /// /// Override component pipeline destruction. @@ -941,15 +945,6 @@ void UpdateCachedSpline() m_CachedTension = m_SplineCurvature; } } - -#if UNITY_EDITOR - [RuntimeInitializeOnLoadMethod] - private static void ResetStaticsOnLoad() - { - //CreateRigOverride = null; - //DestroyRigOverride = null; - } -#endif } } #endif diff --git a/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs index 6e98dd2bd..11e22c8bf 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs @@ -208,15 +208,6 @@ protected void OnValidate() m_Lens.Validate(); } -#if UNITY_EDITOR - [RuntimeInitializeOnLoadMethod] - private static void ResetStaticsOnLoad() - { - //CreatePipelineOverride = null; - //DestroyPipelineOverride = null; - } -#endif - void OnTransformChildrenChanged() { InvalidateComponentPipeline(); @@ -235,7 +226,9 @@ void Reset() /// This needs to be done by the editor to support Undo. /// The override must do exactly the same thing as the CreatePipeline method in this class. /// +#pragma warning disable UDR0001 public static CreatePipelineDelegate CreatePipelineOverride; +#pragma warning restore UDR0001 /// /// Override component pipeline creation. @@ -254,7 +247,9 @@ public delegate Transform CreatePipelineDelegate( /// Override component pipeline destruction. /// This needs to be done by the editor to support Undo. /// +#pragma warning disable UDR0001 public static DestroyPipelineDelegate DestroyPipelineOverride; +#pragma warning restore UDR0001 /// /// Override component pipeline destruction. From 58a29e7cc389b586ea2711ed7254a5b6dc2f7882 Mon Sep 17 00:00:00 2001 From: sim-bz Date: Tue, 17 Feb 2026 10:55:25 -0500 Subject: [PATCH 6/6] Updated version and changelog. --- com.unity.cinemachine/CHANGELOG.md | 3 ++- com.unity.cinemachine/package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/com.unity.cinemachine/CHANGELOG.md b/com.unity.cinemachine/CHANGELOG.md index 4cd12e9c1..18f5a43be 100644 --- a/com.unity.cinemachine/CHANGELOG.md +++ b/com.unity.cinemachine/CHANGELOG.md @@ -4,7 +4,7 @@ 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.6-pre.1] - 2026-02-05 +## [3.1.6-pre.2] - 2026-02-17 ### Bugfixes - Fixed look at being ignored in third person camera when camera is navel gazing. @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed - Converted code using InstanceID references and API to EntityID. +- Added support for fast enter play mode. ## [3.1.5] - 2025-10-21 diff --git a/com.unity.cinemachine/package.json b/com.unity.cinemachine/package.json index d0055a460..0e24b0542 100644 --- a/com.unity.cinemachine/package.json +++ b/com.unity.cinemachine/package.json @@ -1,7 +1,7 @@ { "name": "com.unity.cinemachine", "displayName": "Cinemachine", - "version": "3.1.6-pre.1", + "version": "3.1.6-pre.2", "unity": "2022.3", "description": "Smart camera tools for passionate creators. \n\nCinemachine 3 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": [