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/Editor/Obsolete/CinemachineFreeLookEditor.cs b/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs index 4d90f3813..710c147b9 100644 --- a/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs +++ b/com.unity.cinemachine/Editor/Obsolete/CinemachineFreeLookEditor.cs @@ -172,65 +172,67 @@ void UpdateRigEditor() } } - /// - /// Register with CinemachineFreeLook to create the pipeline in an undo-friendly manner - /// - [InitializeOnLoad] - class CreateRigWithUndo + static CinemachineVirtualCamera CreateRigOverride(CinemachineFreeLook vcam, string name, CinemachineVirtualCamera copyFrom) { - static CreateRigWithUndo() + // Recycle the game object if it exists + GameObject go = null; + foreach (Transform child in vcam.transform) { - CinemachineFreeLook.CreateRigOverride - = (CinemachineFreeLook vcam, string name, CinemachineVirtualCamera copyFrom) => + if (child.gameObject.name == name) { - // Recycle the game object if it exists - GameObject go = null; - foreach (Transform child in vcam.transform) - { - if (child.gameObject.name == name) - { - 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"); - } - - // 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) => - { - var vcam = rig.GetComponent(); - if (vcam != null) - { - vcam.DestroyPipeline(); - Undo.DestroyObjectImmediate(vcam); - } - }; + 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"); + } + + // 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; + } + + static void DestroyRigOverride(GameObject rig) + { + var vcam = rig.GetComponent(); + if (vcam != null) + { + 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 b59f6f4a2..2fe983a15 100644 --- a/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs +++ b/com.unity.cinemachine/Editor/Obsolete/CinemachineVirtualCameraEditor.cs @@ -162,66 +162,68 @@ void ResetTargetOnUndo() (targets[i] as CinemachineVirtualCamera).InvalidateComponentPipeline(); } - /// - /// Register with CinemachineVirtualCamera to create the pipeline in an undo-friendly manner - /// - [InitializeOnLoad] - class CreatePipelineWithUndo + static Transform CreatePipelineOverride(CinemachineVirtualCamera vcam, string name, CinemachineComponentBase[] copyFrom) { - static CreatePipelineWithUndo() + // Recycle existing pipeline child (if any) + GameObject go = null; + foreach (Transform child in vcam.transform) { - CinemachineVirtualCamera.CreatePipelineOverride = - (CinemachineVirtualCamera vcam, string name, CinemachineComponentBase[] copyFrom) => + if (child.GetComponent() != null) { - // 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) - { - // 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); + 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); + } - // If copying, transfer the components - if (copyFrom != null) - { - foreach (Component c in copyFrom) - { - Component copy = Undo.AddComponent(go, c.GetType()); - Undo.RecordObject(copy, "copying pipeline"); - ReflectionHelpers.CopyFields(c, copy); - } - } - return go.transform; - }; + var oldStuff = go.GetComponents(); + foreach (var c in oldStuff) + Undo.DestroyObjectImmediate(c); - CinemachineVirtualCamera.DestroyPipelineOverride = (GameObject pipeline) => + // If copying, transfer the components + if (copyFrom != null) + { + foreach (Component c in copyFrom) { - 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); - }; + Component copy = Undo.AddComponent(go, c.GetType()); + Undo.RecordObject(copy, "copying pipeline"); + ReflectionHelpers.CopyFields(c, copy); + } } + return go.transform; + } + + 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/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/Behaviours/CinemachineStoryboard.cs b/com.unity.cinemachine/Runtime/Behaviours/CinemachineStoryboard.cs index 5728eff63..87ed3cc05 100644 --- a/com.unity.cinemachine/Runtime/Behaviours/CinemachineStoryboard.cs +++ b/com.unity.cinemachine/Runtime/Behaviours/CinemachineStoryboard.cs @@ -446,6 +446,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/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/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 4f600e6b4..cf63db4c1 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]; diff --git a/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs b/com.unity.cinemachine/Runtime/Core/CinemachineCore.cs index 6bc7eaae3..f8142b4c3 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: @@ -102,20 +104,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 s_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 +129,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, @@ -190,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 @@ -207,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. @@ -368,5 +382,24 @@ 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; + 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..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) { @@ -129,5 +126,15 @@ 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_UpdateStatus.Clear(); + s_LastUpdateContext = null; + } +#endif } } diff --git a/com.unity.cinemachine/Runtime/Debug/CinemachineDebug.cs b/com.unity.cinemachine/Runtime/Debug/CinemachineDebug.cs index ad2b1e7b5..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. @@ -148,5 +148,15 @@ 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; + OnGUIHandlers = null; + GameViewGuidesEnabled = false; + } +#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/CinemachineFreeLook.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineFreeLook.cs index 83ae3133f..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. 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/Deprecated/CinemachineVirtualCamera.cs b/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs index e25e8f5b7..11e22c8bf 100644 --- a/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs +++ b/com.unity.cinemachine/Runtime/Deprecated/CinemachineVirtualCamera.cs @@ -226,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. @@ -245,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. diff --git a/com.unity.cinemachine/Runtime/Helpers/CinemachineInputAxisController.cs b/com.unity.cinemachine/Runtime/Helpers/CinemachineInputAxisController.cs index b301427f6..3760e3a1e 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/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) 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; 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": [