ClipEditor.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEngine.Playables;
  4. using UnityEngine.Timeline;
  5. namespace UnityEditor.Timeline
  6. {
  7. /// <summary>
  8. /// Description of the on-screen area where a clip is drawn
  9. /// </summary>
  10. public struct ClipBackgroundRegion
  11. {
  12. /// <summary>
  13. /// The rectangle where the background of the clip is drawn.
  14. /// </summary>
  15. /// <remarks>
  16. /// The rectangle is clipped to the screen. The rectangle does not include clip borders.
  17. /// </remarks>
  18. public Rect position { get; private set; }
  19. /// <summary>
  20. /// The start time of the region, relative to the clip.
  21. /// </summary>
  22. public double startTime { get; private set; }
  23. /// <summary>
  24. /// The end time of the region, relative to the clip.
  25. /// </summary>
  26. public double endTime { get; private set; }
  27. /// <summary>
  28. /// Constructor
  29. /// </summary>
  30. /// <param name="_position"></param>
  31. /// <param name="_startTime"></param>
  32. /// <param name="_endTime"></param>
  33. public ClipBackgroundRegion(Rect _position, double _startTime, double _endTime)
  34. {
  35. position = _position;
  36. startTime = _startTime;
  37. endTime = _endTime;
  38. }
  39. public override bool Equals(object obj)
  40. {
  41. if (!(obj is ClipBackgroundRegion))
  42. return false;
  43. return Equals((ClipBackgroundRegion)obj);
  44. }
  45. public bool Equals(ClipBackgroundRegion other)
  46. {
  47. return position.Equals(other.position) &&
  48. startTime == other.startTime &&
  49. endTime == other.endTime;
  50. }
  51. public override int GetHashCode()
  52. {
  53. return HashUtility.CombineHash(
  54. position.GetHashCode(),
  55. startTime.GetHashCode(),
  56. endTime.GetHashCode()
  57. );
  58. }
  59. public static bool operator==(ClipBackgroundRegion region1, ClipBackgroundRegion region2)
  60. {
  61. return region1.Equals(region2);
  62. }
  63. public static bool operator!=(ClipBackgroundRegion region1, ClipBackgroundRegion region2)
  64. {
  65. return !region1.Equals(region2);
  66. }
  67. }
  68. /// <summary>
  69. /// The user-defined options for drawing a clip.
  70. /// </summary>
  71. public struct ClipDrawOptions
  72. {
  73. private IEnumerable<Texture2D> m_Icons;
  74. /// <summary>
  75. /// Text that indicates if the clip should display an error.
  76. /// </summary>
  77. /// <remarks>
  78. /// If the error text is not empty or null, then the clip displays a warning. The error text is used as the tooltip.
  79. /// </remarks>
  80. public string errorText { get; set; }
  81. /// <summary>
  82. /// The tooltip to show for the clip.
  83. /// </summary>
  84. public string tooltip { get; set; }
  85. /// <summary>
  86. /// The color drawn under the clip. By default, the color is the same as the track color.
  87. /// </summary>
  88. public Color highlightColor { get; set; }
  89. /// <summary>
  90. /// Icons to display on the clip.
  91. /// </summary>
  92. public IEnumerable<Texture2D> icons
  93. {
  94. get { return m_Icons ?? System.Linq.Enumerable.Empty<Texture2D>(); }
  95. set { m_Icons = value;}
  96. }
  97. public override bool Equals(object obj)
  98. {
  99. if (!(obj is ClipDrawOptions))
  100. return false;
  101. return Equals((ClipDrawOptions)obj);
  102. }
  103. public bool Equals(ClipDrawOptions other)
  104. {
  105. return errorText == other.errorText &&
  106. tooltip == other.tooltip &&
  107. highlightColor == other.highlightColor &&
  108. System.Linq.Enumerable.SequenceEqual(icons, other.icons);
  109. }
  110. public override int GetHashCode()
  111. {
  112. return HashUtility.CombineHash(
  113. errorText != null ? errorText.GetHashCode() : 0,
  114. tooltip != null ? tooltip.GetHashCode() : 0,
  115. highlightColor.GetHashCode(),
  116. icons != null ? icons.GetHashCode() : 0
  117. );
  118. }
  119. public static bool operator==(ClipDrawOptions options1, ClipDrawOptions options2)
  120. {
  121. return options1.Equals(options2);
  122. }
  123. public static bool operator!=(ClipDrawOptions options1, ClipDrawOptions options2)
  124. {
  125. return !options1.Equals(options2);
  126. }
  127. }
  128. /// <summary>
  129. /// Use this class to customize clip types in the TimelineEditor.
  130. /// </summary>
  131. public class ClipEditor
  132. {
  133. static readonly string k_NoPlayableAssetError = LocalizationDatabase.GetLocalizedString("This clip does not contain a valid playable asset");
  134. static readonly string k_ScriptLoadError = LocalizationDatabase.GetLocalizedString("The associated script can not be loaded");
  135. internal readonly bool supportsSubTimelines;
  136. /// <summary>
  137. /// Default constructor
  138. /// </summary>
  139. public ClipEditor()
  140. {
  141. supportsSubTimelines = TypeUtility.HasOverrideMethod(GetType(), nameof(GetSubTimelines));
  142. }
  143. /// <summary>
  144. /// Implement this method to override the default options for drawing a clip.
  145. /// </summary>
  146. /// <param name="clip">The clip being drawn.</param>
  147. /// <returns>The options for drawing a clip.</returns>
  148. public virtual ClipDrawOptions GetClipOptions(TimelineClip clip)
  149. {
  150. return new ClipDrawOptions()
  151. {
  152. errorText = GetErrorText(clip),
  153. tooltip = string.Empty,
  154. highlightColor = GetDefaultHighlightColor(clip),
  155. icons = System.Linq.Enumerable.Empty<Texture2D>()
  156. };
  157. }
  158. /// <summary>
  159. /// Override this method to draw a background for a clip .
  160. /// </summary>
  161. /// <param name="clip">The clip being drawn.</param>
  162. /// <param name="region">The on-screen area where the clip is drawn.</param>
  163. public virtual void DrawBackground(TimelineClip clip, ClipBackgroundRegion region)
  164. {
  165. }
  166. /// <summary>
  167. /// Called when a clip is created.
  168. /// </summary>
  169. /// <param name="clip">The newly created clip.</param>
  170. /// <param name="track">The track that the clip is assigned to.</param>
  171. /// <param name="clonedFrom">The source that the clip was copied from. This can be set to null if the clip is not a copy.</param>
  172. /// <remarks>
  173. /// The callback occurs before the clip is assigned to the track.
  174. /// </remarks>
  175. public virtual void OnCreate(TimelineClip clip, TrackAsset track, TimelineClip clonedFrom)
  176. {
  177. }
  178. /// <summary>
  179. /// Gets the error text for the specified clip.
  180. /// </summary>
  181. /// <param name="clip">The clip being drawn.</param>
  182. /// <returns>Returns the error text to be displayed as the tool tip for the clip. If there is no error to be displayed, this method returns string.Empty.</returns>
  183. public string GetErrorText(TimelineClip clip)
  184. {
  185. if (clip == null || clip.asset == null)
  186. return k_NoPlayableAssetError;
  187. var playableAsset = clip.asset as ScriptableObject;
  188. if (playableAsset == null || MonoScript.FromScriptableObject(playableAsset) == null)
  189. return k_ScriptLoadError;
  190. return string.Empty;
  191. }
  192. /// <summary>
  193. /// The color drawn under the clip. By default, the color is the same as the track color.
  194. /// </summary>
  195. /// <param name="clip">The clip being drawn.</param>
  196. /// <returns>Returns the highlight color of the clip being drawn.</returns>
  197. public Color GetDefaultHighlightColor(TimelineClip clip)
  198. {
  199. if (clip == null)
  200. return Color.white;
  201. return TrackResourceCache.GetTrackColor(clip.parentTrack);
  202. }
  203. /// <summary>
  204. /// Called when a clip is changed by the Editor.
  205. /// </summary>
  206. /// <param name="clip">The clip that changed.</param>
  207. public virtual void OnClipChanged(TimelineClip clip)
  208. {
  209. }
  210. /// <summary>
  211. /// Gets the sub-timelines for a specific clip. Implement this method if your clip supports playing nested timelines.
  212. /// </summary>
  213. /// <param name="clip">The clip with the ControlPlayableAsset.</param>
  214. /// <param name="director">The playable director driving the Timeline Clip. This may not be the same as TimelineEditor.inspectedDirector.</param>
  215. /// <param name="subTimelines">Specify the sub-timelines to control.</param>
  216. public virtual void GetSubTimelines(TimelineClip clip, PlayableDirector director, List<PlayableDirector> subTimelines)
  217. {
  218. }
  219. }
  220. }