File size: 5,578 Bytes
18a519f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | 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();
}
}
}
|