CinemachineShotClipEditor.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #if !UNITY_2019_1_OR_NEWER
  2. #define CINEMACHINE_TIMELINE
  3. #endif
  4. #if CINEMACHINE_TIMELINE && UNITY_2019_2_OR_NEWER
  5. using UnityEngine.Timeline;
  6. using UnityEditor.Timeline;
  7. using Cinemachine;
  8. using UnityEditor;
  9. using UnityEngine;
  10. using UnityEngine.Playables;
  11. [CustomTimelineEditor(typeof(CinemachineShot))]
  12. public class CinemachineShotClipEditor : ClipEditor
  13. {
  14. [InitializeOnLoad]
  15. class EditorInitialize
  16. {
  17. static EditorInitialize() { CinemachineMixer.GetMasterPlayableDirector = GetMasterDirector; }
  18. static PlayableDirector GetMasterDirector() { return TimelineEditor.masterDirector; }
  19. }
  20. public delegate double TimelineGlobalToLocalTimeDelegate(double globalTime);
  21. public static TimelineGlobalToLocalTimeDelegate TimelineGlobalToLocalTime = NoTimeConversion;
  22. public static double NoTimeConversion(double time) { return time; }
  23. public override ClipDrawOptions GetClipOptions(TimelineClip clip)
  24. {
  25. var shotClip = (CinemachineShot) clip.asset;
  26. var clipOptions = base.GetClipOptions(clip);
  27. if (shotClip != null)
  28. {
  29. var director = TimelineEditor.inspectedDirector;
  30. if (director != null)
  31. {
  32. var vcam = shotClip.VirtualCamera.Resolve(director);
  33. if (vcam == null)
  34. clipOptions.errorText = "A virtual camera must be assigned";
  35. else
  36. clipOptions.tooltip = vcam.Name;
  37. }
  38. }
  39. return clipOptions;
  40. }
  41. public override void OnClipChanged(TimelineClip clip)
  42. {
  43. var shotClip = (CinemachineShot)clip.asset;
  44. if (shotClip == null)
  45. return;
  46. if (shotClip.DisplayName != null && shotClip.DisplayName.Length != 0)
  47. clip.displayName = shotClip.DisplayName;
  48. else
  49. {
  50. var director = TimelineEditor.inspectedDirector;
  51. if (director != null)
  52. {
  53. var vcam = shotClip.VirtualCamera.Resolve(director);
  54. if (vcam != null)
  55. clip.displayName = vcam.Name;
  56. }
  57. }
  58. }
  59. public override void OnCreate(TimelineClip clip, TrackAsset track, TimelineClip clonedFrom)
  60. {
  61. base.OnCreate(clip, track, clonedFrom);
  62. if (CinemachineShotEditor.AutoCreateShotFromSceneView)
  63. {
  64. var asset = clip.asset as CinemachineShot;
  65. var vcam = CinemachineShotEditor.CreateStaticVcamFromSceneView();
  66. var d = TimelineEditor.inspectedDirector;
  67. if (d != null && d.GetReferenceValue(asset.VirtualCamera.exposedName, out bool idValid) == null)
  68. {
  69. asset.VirtualCamera.exposedName = System.Guid.NewGuid().ToString();
  70. d.SetReferenceValue(asset.VirtualCamera.exposedName, vcam);
  71. }
  72. }
  73. }
  74. GUIContent kUndamped = new GUIContent("UNCACHED");
  75. public override void DrawBackground(TimelineClip clip, ClipBackgroundRegion region)
  76. {
  77. base.DrawBackground(clip, region);
  78. if (Application.isPlaying || !TargetPositionCache.UseCache
  79. || TargetPositionCache.CacheMode == TargetPositionCache.Mode.Disabled
  80. || TimelineEditor.inspectedDirector == null)
  81. {
  82. return;
  83. }
  84. // Draw the cache indicator over the cached region
  85. var cacheRange = TargetPositionCache.CacheTimeRange;
  86. if (!cacheRange.IsEmpty)
  87. {
  88. cacheRange.Start = (float)TimelineGlobalToLocalTime(cacheRange.Start);
  89. cacheRange.End = (float)TimelineGlobalToLocalTime(cacheRange.End);
  90. // Clip cacheRange to rect
  91. float start = (float)region.startTime;
  92. float end = (float)region.endTime;
  93. cacheRange.Start = Mathf.Max((float)clip.ToLocalTime(cacheRange.Start), start);
  94. cacheRange.End = Mathf.Min((float)clip.ToLocalTime(cacheRange.End), end);
  95. var r = region.position;
  96. var a = r.x + r.width * (cacheRange.Start - start) / (end - start);
  97. var b = r.x + r.width * (cacheRange.End - start) / (end - start);
  98. r.x = a; r.width = b-a;
  99. r.y += r.height; r.height *= 0.2f; r.y -= r.height;
  100. EditorGUI.DrawRect(r, new Color(0.1f, 0.2f, 0.8f, 0.6f));
  101. }
  102. // Draw the "UNCACHED" indicator, if appropriate
  103. if (!TargetPositionCache.IsRecording && !TargetPositionCache.CurrentPlaybackTimeValid)
  104. {
  105. var r = region.position;
  106. var t = clip.ToLocalTime(TimelineGlobalToLocalTime(TimelineEditor.masterDirector.time));
  107. var pos = r.x + r.width
  108. * (float)((t - region.startTime) / (region.endTime - region.startTime));
  109. var s = EditorStyles.miniLabel.CalcSize(kUndamped);
  110. r.width = s.x; r.x = pos - r.width / 2;
  111. var c = GUI.color;
  112. GUI.color = Color.yellow;
  113. EditorGUI.LabelField(r, kUndamped, EditorStyles.miniLabel);
  114. GUI.color = c;
  115. }
  116. }
  117. }
  118. #endif