Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMCL-1606: TargetPositionCache needs to be public #1023

Merged
merged 2 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.cinemachine/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Changed
- The presence of a tracking target no longer affects whether the CinemachineCamera state's position and rotation are pushed back to the transform.
- Made TargetPositionCache.GetTargetPosition() and TargetPositionCache.GetTargetRotation() public, so that custom classes can support cached timeline scrubbing.

### Bugfixes
- Sometimes a deeply-nested passive camera's position would creep due to precision inaccuracies.
Expand Down
58 changes: 37 additions & 21 deletions com.unity.cinemachine/Runtime/Core/TargetPositionCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@

namespace Unity.Cinemachine
{
internal class TargetPositionCache
/// <summary>
/// Use this class to support caching of Cinemachine target positions and rotations for the
/// purposes of timeline scrubbing in the Editor. At runtime, the public methods in this class
/// simply return the uncached values from the target's transform.
///
/// Cinemachine behaviours and extensions that support timeline scrubbing should use the
/// GetTargetPosition and GetTargetRotation static methods when accessing the target's position or rotation.
/// </summary>
public class TargetPositionCache
{
public static bool UseCache;
public const float CacheStepSize = 1 / 60.0f;
public enum Mode { Disabled, Record, Playback }
internal static bool UseCache;
internal const float CacheStepSize = 1 / 60.0f;
internal enum Mode { Disabled, Record, Playback }

static Mode m_CacheMode = Mode.Disabled;

Expand All @@ -16,7 +24,7 @@ public enum Mode { Disabled, Record, Playback }
static void OnSceneLoaded(UnityEngine.SceneManagement.Scene scene, UnityEngine.SceneManagement.LoadSceneMode mode) { ClearCache(); }
#endif

public static Mode CacheMode
internal static Mode CacheMode
{
get => m_CacheMode;
set
Expand All @@ -33,15 +41,15 @@ public static Mode CacheMode
}
}

public static bool IsRecording => UseCache && m_CacheMode == Mode.Record;
public static bool CurrentPlaybackTimeValid => UseCache && m_CacheMode == Mode.Playback && HasCurrentTime;
public static bool IsEmpty => CacheTimeRange.IsEmpty;
internal static bool IsRecording => UseCache && m_CacheMode == Mode.Record;
internal static bool CurrentPlaybackTimeValid => UseCache && m_CacheMode == Mode.Playback && HasCurrentTime;
internal static bool IsEmpty => CacheTimeRange.IsEmpty;

public static float CurrentTime;
internal static float CurrentTime;

// These are used during recording to manage camera cuts
public static int CurrentFrame;
public static bool IsCameraCut;
internal static int CurrentFrame;
internal static bool IsCameraCut;

class CacheCurve
{
Expand Down Expand Up @@ -170,7 +178,7 @@ public void CreateCurves()

static Dictionary<Transform, CacheEntry> m_Cache;

public struct TimeRange
internal struct TimeRange
{
public float Start;
public float End;
Expand All @@ -187,10 +195,10 @@ public void Include(float time)
}
}
static TimeRange m_CacheTimeRange;
public static TimeRange CacheTimeRange { get => m_CacheTimeRange; }
public static bool HasCurrentTime { get => m_CacheTimeRange.Contains(CurrentTime); }
internal static TimeRange CacheTimeRange { get => m_CacheTimeRange; }
internal static bool HasCurrentTime { get => m_CacheTimeRange.Contains(CurrentTime); }

public static void ClearCache()
internal static void ClearCache()
{
m_Cache = CacheMode == Mode.Disabled ? null : new Dictionary<Transform, CacheEntry>();
m_CacheTimeRange = TimeRange.Empty;
Expand All @@ -211,11 +219,15 @@ static void CreatePlaybackCurves()
const float kWraparoundSlush = 0.1f;

/// <summary>
/// If Recording, will log the target position at the CurrentTime.
/// Otherwise, will fetch the cached position at CurrentTime.
/// When using Timeline in Edit mode:
/// - If you're Recording, the method logs the target position at the CurrentTime.
/// - Otherwise, it fetches the cached position at CurrentTime.
///
/// When using Timeline in Play mode, and when you're not scrubbing it:
/// - The method returns the position directly from the Transform.
/// </summary>
/// <param name="target">Target whose transform is tracked</param>
/// <param name="position">Target's position at CurrentTime</param>
/// <returns>The effective position of the target.</returns>
public static Vector3 GetTargetPosition(Transform target)
{
if (!UseCache || CacheMode == Mode.Disabled)
Expand Down Expand Up @@ -252,11 +264,15 @@ public static Vector3 GetTargetPosition(Transform target)
}

/// <summary>
/// If Recording, will log the target rotation at the CurrentTime.
/// Otherwise, will fetch the cached position at CurrentTime.
/// When using Timeline in Edit mode:
/// - If you're Recording, the method logs the target position at the CurrentTime.
/// - Otherwise, it fetches the cached position at CurrentTime.
///
/// When using Timeline in Play mode, and when you're not scrubbing it:
/// - The method returns the position directly from the Transform.
/// </summary>
/// <param name="target">Target whose transform is tracked</param>
/// <param name="rotation">Target's rotation at CurrentTime</param>
/// <returns>The effective position of the target.</returns>
public static Quaternion GetTargetRotation(Transform target)
{
if (CacheMode == Mode.Disabled)
Expand Down
Loading