123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- using System;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.Playables;
- using UnityEngine.Timeline;
- using Object = UnityEngine.Object;
-
- namespace UnityEditor.Timeline
- {
- static class BindingUtility
- {
- public enum BindingAction
- {
- DoNotBind,
- BindDirectly,
- BindToExistingComponent,
- BindToMissingComponent
- }
-
- const string k_BindingOperation = "Bind Track";
-
- public static void Bind(PlayableDirector director, TrackAsset bindTo, Object objectToBind)
- {
- if (director == null || bindTo == null || TimelineWindow.instance == null)
- return;
-
- if (director.GetGenericBinding(bindTo) == objectToBind)
- return;
-
- TimelineWindow.instance.state.previewMode = false; // returns all objects to previous state
- TimelineUndo.PushUndo(director, k_BindingOperation);
- director.SetGenericBinding(bindTo, objectToBind);
- TimelineWindow.instance.state.rebuildGraph = true;
- }
-
- public static void BindWithEditorValidation(PlayableDirector director, TrackAsset bindTo, Object objectToBind)
- {
- TrackEditor trackEditor = CustomTimelineEditorCache.GetTrackEditor(bindTo);
- Object validatedObject = trackEditor.GetBindingFrom_Safe(objectToBind, bindTo);
- Bind(director, bindTo, validatedObject);
- }
-
- public static void BindWithInteractiveEditorValidation(PlayableDirector director, TrackAsset bindTo, Object objectToBind)
- {
- TrackEditor trackEditor = CustomTimelineEditorCache.GetTrackEditor(bindTo);
- if (trackEditor.SupportsBindingAssign())
- BindWithEditorValidation(director, bindTo, objectToBind);
- else
- {
- Type bindingType = TypeUtility.GetTrackBindingAttribute(bindTo.GetType())?.type;
- BindingAction action = GetBindingAction(bindingType, objectToBind);
- if (action == BindingAction.BindToMissingComponent)
- InteractiveBindToMissingComponent(director, bindTo, objectToBind, bindingType);
- else
- {
- var validatedObject = GetBinding(action, objectToBind, bindingType);
- Bind(director, bindTo, validatedObject);
- }
- }
- }
-
- public static BindingAction GetBindingAction(Type requiredBindingType, Object objectToBind)
- {
- if (requiredBindingType == null || objectToBind == null)
- return BindingAction.DoNotBind;
-
- // prevent drag and drop of prefab assets
- if (PrefabUtility.IsPartOfPrefabAsset(objectToBind))
- return BindingAction.DoNotBind;
-
- if (requiredBindingType.IsInstanceOfType(objectToBind))
- return BindingAction.BindDirectly;
-
- var draggedGameObject = objectToBind as GameObject;
-
- if (!typeof(Component).IsAssignableFrom(requiredBindingType) || draggedGameObject == null)
- return BindingAction.DoNotBind;
-
- if (draggedGameObject.GetComponent(requiredBindingType) == null)
- return BindingAction.BindToMissingComponent;
-
- return BindingAction.BindToExistingComponent;
- }
-
- public static Object GetBinding(BindingAction bindingAction, Object objectToBind, Type requiredBindingType)
- {
- if (objectToBind == null) return null;
-
- switch (bindingAction)
- {
- case BindingAction.BindDirectly:
- {
- return objectToBind;
- }
- case BindingAction.BindToExistingComponent:
- {
- var gameObjectBeingDragged = objectToBind as GameObject;
- Debug.Assert(gameObjectBeingDragged != null, "The object being dragged was detected as being a GameObject");
- return gameObjectBeingDragged.GetComponent(requiredBindingType);
- }
- case BindingAction.BindToMissingComponent:
- {
- var gameObjectBeingDragged = objectToBind as GameObject;
- Debug.Assert(gameObjectBeingDragged != null, "The object being dragged was detected as being a GameObject");
- return Undo.AddComponent(gameObjectBeingDragged, requiredBindingType);
- }
- default:
- return null;
- }
- }
-
- static void InteractiveBindToMissingComponent(PlayableDirector director, TrackAsset bindTo, Object objectToBind, Type requiredComponentType)
- {
- var gameObjectBeingDragged = objectToBind as GameObject;
- Debug.Assert(gameObjectBeingDragged != null, "The object being dragged was detected as being a GameObject");
-
- string typeNameOfComponent = requiredComponentType.ToString().Split(".".ToCharArray()).Last();
- var bindMenu = new GenericMenu();
- bindMenu.AddItem(
- EditorGUIUtility.TextContent("Create " + typeNameOfComponent + " on " + gameObjectBeingDragged.name),
- false,
- nullParam => Bind(director, bindTo, Undo.AddComponent(gameObjectBeingDragged, requiredComponentType)),
- null);
-
- bindMenu.AddSeparator("");
- bindMenu.AddItem(EditorGUIUtility.TrTextContent("Cancel"), false, userData => { }, null);
- bindMenu.ShowAsContext();
- }
- }
- }
|