No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BindingUtility.cs 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using System;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEngine.Playables;
  5. using UnityEngine.Timeline;
  6. using Object = UnityEngine.Object;
  7. namespace UnityEditor.Timeline
  8. {
  9. static class BindingUtility
  10. {
  11. public enum BindingAction
  12. {
  13. DoNotBind,
  14. BindDirectly,
  15. BindToExistingComponent,
  16. BindToMissingComponent
  17. }
  18. const string k_BindingOperation = "Bind Track";
  19. public static void Bind(PlayableDirector director, TrackAsset bindTo, Object objectToBind)
  20. {
  21. if (director == null || bindTo == null || TimelineWindow.instance == null)
  22. return;
  23. if (director.GetGenericBinding(bindTo) == objectToBind)
  24. return;
  25. TimelineWindow.instance.state.previewMode = false; // returns all objects to previous state
  26. TimelineUndo.PushUndo(director, k_BindingOperation);
  27. director.SetGenericBinding(bindTo, objectToBind);
  28. TimelineWindow.instance.state.rebuildGraph = true;
  29. }
  30. public static void BindWithEditorValidation(PlayableDirector director, TrackAsset bindTo, Object objectToBind)
  31. {
  32. TrackEditor trackEditor = CustomTimelineEditorCache.GetTrackEditor(bindTo);
  33. Object validatedObject = trackEditor.GetBindingFrom_Safe(objectToBind, bindTo);
  34. Bind(director, bindTo, validatedObject);
  35. }
  36. public static void BindWithInteractiveEditorValidation(PlayableDirector director, TrackAsset bindTo, Object objectToBind)
  37. {
  38. TrackEditor trackEditor = CustomTimelineEditorCache.GetTrackEditor(bindTo);
  39. if (trackEditor.SupportsBindingAssign())
  40. BindWithEditorValidation(director, bindTo, objectToBind);
  41. else
  42. {
  43. Type bindingType = TypeUtility.GetTrackBindingAttribute(bindTo.GetType())?.type;
  44. BindingAction action = GetBindingAction(bindingType, objectToBind);
  45. if (action == BindingAction.BindToMissingComponent)
  46. InteractiveBindToMissingComponent(director, bindTo, objectToBind, bindingType);
  47. else
  48. {
  49. var validatedObject = GetBinding(action, objectToBind, bindingType);
  50. Bind(director, bindTo, validatedObject);
  51. }
  52. }
  53. }
  54. public static BindingAction GetBindingAction(Type requiredBindingType, Object objectToBind)
  55. {
  56. if (requiredBindingType == null || objectToBind == null)
  57. return BindingAction.DoNotBind;
  58. // prevent drag and drop of prefab assets
  59. if (PrefabUtility.IsPartOfPrefabAsset(objectToBind))
  60. return BindingAction.DoNotBind;
  61. if (requiredBindingType.IsInstanceOfType(objectToBind))
  62. return BindingAction.BindDirectly;
  63. var draggedGameObject = objectToBind as GameObject;
  64. if (!typeof(Component).IsAssignableFrom(requiredBindingType) || draggedGameObject == null)
  65. return BindingAction.DoNotBind;
  66. if (draggedGameObject.GetComponent(requiredBindingType) == null)
  67. return BindingAction.BindToMissingComponent;
  68. return BindingAction.BindToExistingComponent;
  69. }
  70. public static Object GetBinding(BindingAction bindingAction, Object objectToBind, Type requiredBindingType)
  71. {
  72. if (objectToBind == null) return null;
  73. switch (bindingAction)
  74. {
  75. case BindingAction.BindDirectly:
  76. {
  77. return objectToBind;
  78. }
  79. case BindingAction.BindToExistingComponent:
  80. {
  81. var gameObjectBeingDragged = objectToBind as GameObject;
  82. Debug.Assert(gameObjectBeingDragged != null, "The object being dragged was detected as being a GameObject");
  83. return gameObjectBeingDragged.GetComponent(requiredBindingType);
  84. }
  85. case BindingAction.BindToMissingComponent:
  86. {
  87. var gameObjectBeingDragged = objectToBind as GameObject;
  88. Debug.Assert(gameObjectBeingDragged != null, "The object being dragged was detected as being a GameObject");
  89. return Undo.AddComponent(gameObjectBeingDragged, requiredBindingType);
  90. }
  91. default:
  92. return null;
  93. }
  94. }
  95. static void InteractiveBindToMissingComponent(PlayableDirector director, TrackAsset bindTo, Object objectToBind, Type requiredComponentType)
  96. {
  97. var gameObjectBeingDragged = objectToBind as GameObject;
  98. Debug.Assert(gameObjectBeingDragged != null, "The object being dragged was detected as being a GameObject");
  99. string typeNameOfComponent = requiredComponentType.ToString().Split(".".ToCharArray()).Last();
  100. var bindMenu = new GenericMenu();
  101. bindMenu.AddItem(
  102. EditorGUIUtility.TextContent("Create " + typeNameOfComponent + " on " + gameObjectBeingDragged.name),
  103. false,
  104. nullParam => Bind(director, bindTo, Undo.AddComponent(gameObjectBeingDragged, requiredComponentType)),
  105. null);
  106. bindMenu.AddSeparator("");
  107. bindMenu.AddItem(EditorGUIUtility.TrTextContent("Cancel"), false, userData => { }, null);
  108. bindMenu.ShowAsContext();
  109. }
  110. }
  111. }