CinemachineShotClipEditor.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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 = DefaultTimeConversion;
  22. #if CINEMACHINE_TIMELINE_1_5_0
  23. static double DefaultTimeConversion(double time) { return TimelineEditor.GetInspectedTimeFromMasterTime(time); }
  24. #else
  25. static double DefaultTimeConversion(double time) { return time; }
  26. #endif
  27. public override ClipDrawOptions GetClipOptions(TimelineClip clip)
  28. {
  29. var shotClip = (CinemachineShot) clip.asset;
  30. var clipOptions = base.GetClipOptions(clip);
  31. if (shotClip != null)
  32. {
  33. var director = TimelineEditor.inspectedDirector;
  34. if (director != null)
  35. {
  36. var vcam = shotClip.VirtualCamera.Resolve(director);
  37. if (vcam == null)
  38. clipOptions.errorText = "A virtual camera must be assigned";
  39. else
  40. clipOptions.tooltip = vcam.Name;
  41. }
  42. }
  43. return clipOptions;
  44. }
  45. public override void OnClipChanged(TimelineClip clip)
  46. {
  47. var shotClip = (CinemachineShot)clip.asset;
  48. if (shotClip == null)
  49. return;
  50. if (shotClip.DisplayName != null && shotClip.DisplayName.Length != 0)
  51. clip.displayName = shotClip.DisplayName;
  52. else
  53. {
  54. var director = TimelineEditor.inspectedDirector;
  55. if (director != null)
  56. {
  57. var vcam = shotClip.VirtualCamera.Resolve(director);
  58. if (vcam != null)
  59. clip.displayName = vcam.Name;
  60. }
  61. }
  62. }
  63. public override void OnCreate(TimelineClip clip, TrackAsset track, TimelineClip clonedFrom)
  64. {
  65. base.OnCreate(clip, track, clonedFrom);
  66. if (CinemachineShotEditor.AutoCreateShotFromSceneView)
  67. {
  68. var asset = clip.asset as CinemachineShot;
  69. var vcam = CinemachineShotEditor.CreatePassiveVcamFromSceneView();
  70. var d = TimelineEditor.inspectedDirector;
  71. if (d != null && d.GetReferenceValue(asset.VirtualCamera.exposedName, out bool idValid) == null)
  72. {
  73. asset.VirtualCamera.exposedName = System.Guid.NewGuid().ToString();
  74. d.SetReferenceValue(asset.VirtualCamera.exposedName, vcam);
  75. }
  76. }
  77. }
  78. GUIContent kUndamped = new GUIContent("UNCACHED");
  79. public override void DrawBackground(TimelineClip clip, ClipBackgroundRegion region)
  80. {
  81. base.DrawBackground(clip, region);
  82. if (Application.isPlaying || !TargetPositionCache.UseCache
  83. || TargetPositionCache.CacheMode == TargetPositionCache.Mode.Disabled
  84. || TimelineEditor.inspectedDirector == null)
  85. {
  86. return;
  87. }
  88. // Draw the cache indicator over the cached region
  89. var cacheRange = TargetPositionCache.CacheTimeRange;
  90. if (!cacheRange.IsEmpty)
  91. {
  92. cacheRange.Start = (float)TimelineGlobalToLocalTime(cacheRange.Start);
  93. cacheRange.End = (float)TimelineGlobalToLocalTime(cacheRange.End);
  94. // Clip cacheRange to rect
  95. float start = (float)region.startTime;
  96. float end = (float)region.endTime;
  97. cacheRange.Start = Mathf.Max((float)clip.ToLocalTime(cacheRange.Start), start);
  98. cacheRange.End = Mathf.Min((float)clip.ToLocalTime(cacheRange.End), end);
  99. var r = region.position;
  100. var a = r.x + r.width * (cacheRange.Start - start) / (end - start);
  101. var b = r.x + r.width * (cacheRange.End - start) / (end - start);
  102. r.x = a; r.width = b-a;
  103. r.y += r.height; r.height *= 0.2f; r.y -= r.height;
  104. EditorGUI.DrawRect(r, new Color(0.1f, 0.2f, 0.8f, 0.6f));
  105. }
  106. // Draw the "UNCACHED" indicator, if appropriate
  107. if (!TargetPositionCache.IsRecording && !TargetPositionCache.CurrentPlaybackTimeValid)
  108. {
  109. var r = region.position;
  110. var t = clip.ToLocalTime(TimelineGlobalToLocalTime(TimelineEditor.masterDirector.time));
  111. var pos = r.x + r.width
  112. * (float)((t - region.startTime) / (region.endTime - region.startTime));
  113. var s = EditorStyles.miniLabel.CalcSize(kUndamped);
  114. r.width = s.x; r.x = pos - r.width / 2;
  115. var c = GUI.color;
  116. GUI.color = Color.yellow;
  117. EditorGUI.LabelField(r, kUndamped, EditorStyles.miniLabel);
  118. GUI.color = c;
  119. }
  120. }
  121. }
  122. #endif