// Called by the Timeline editor to draw the background of a TweenClip.
        public override void DrawBackground(TimelineClip clip, ClipBackgroundRegion region)
        {
            TweenClip asset = clip.asset as TweenClip;

            if (asset == null)
            {
                return;
            }

            PlayableDirector director = TimelineEditor.inspectedDirector;

            if (director == null)
            {
                return;
            }

            Transform startLocation = director.GetReferenceValue(asset.startLocation.exposedName, out bool startFound) as Transform;
            Transform endLocation   = director.GetReferenceValue(asset.endLocation.exposedName, out bool endFound) as Transform;

            if (startFound && startLocation != null)
            {
                EditorGUI.LabelField(region.position, startLocation.gameObject.name, s_StartTextStyle);
            }

            if (endFound && endLocation != null)
            {
                EditorGUI.LabelField(region.position, endLocation.gameObject.name, s_EndTextStyle);
            }
        }
        private void Start()
        {
            mixers = new List <AnimationLayerMixerPlayable>();
            for (var i = 0; i < dir.playableGraph.GetOutputCount(); i++)
            {
                var p = dir.playableGraph.GetRootPlayable(i);
                if (!p.IsValid())
                {
                    continue;
                }
                Debug.Log(p.GetPlayableType());
                Debug.Log("OUTPUT: " + i + " = " + p.GetPlayableType() + ", outputs: " + p.GetOutputCount() + ", inputs: " + p.GetInputCount());
                Traverse(p, mixers);
            }

            var arr = dir.playableAsset.outputs.ToArray();

            for (var i = 0; i < arr.Length; i++)
            {
                var entry = arr[i];

                if (entry.outputTargetType == typeof(Animator))
                {
                    var binding = dir.GetGenericBinding(entry.sourceObject);
                    var b2      = dir.GetReferenceValue(new PropertyName(entry.streamName), out var valid);
                    Debug.Log("BINDING: " + i + ", " + binding + ", " + b2 + " valid=" + valid + "  " + entry.streamName + " - " + entry.sourceObject +
                              ", " + binding);
                    boundAnimators.Add(binding as Animator);
                }
                else
                {
                    var binding = dir.GetGenericBinding(entry.sourceObject);
                    var b2      = dir.GetReferenceValue(new PropertyName(entry.streamName), out var valid);
                    Debug.Log("BINDING: " + i + " is " + entry.outputTargetType + " for " + b2 + ", " + entry.streamName + ", " + binding);
                }
            }

            if (InjectOnStart)
            {
                InjectMixers();
            }

            Debug.Log("-----------");
            if (TimelineUtilities.TryFindTimelinePlayable(dir.playableGraph, out var timeline))
            {
                Debug.Log(timeline.GetPlayableType() + ", " + timeline.GetType());
                if (TimelineUtilities.TryInjectMixer(dir, timeline, GetComponent <Animator>(), out var mixer))
                {
                    Debug.Log("INJECTED MIXER" + mixer);
                }
            }
        }
Esempio n. 3
0
        static ScriptableObject CloneReferencedPlayableAsset(ScriptableObject original, PlayableDirector directorInstance)
        {
            var clone = Object.Instantiate(original);

            TimelineUndo.RegisterCreatedObjectUndo(clone, "Create clip");
            if (clone == null || (clone as IPlayableAsset) == null)
            {
                throw new InvalidCastException("could not cast instantiated object into IPlayableAsset");
            }

            if (directorInstance != null)
            {
                // Use serialize object to make a copy
                var originalObject      = new SerializedObject(original);
                var cloneObject         = new SerializedObject(clone);
                SerializedProperty prop = originalObject.GetIterator();
                if (prop.Next(true))
                {
                    do
                    {
                        cloneObject.CopyFromSerializedProperty(prop);
                    } while (prop.Next(false));
                }
                cloneObject.ApplyModifiedProperties();

                EditorUtility.SetDirty(directorInstance);

                // The exposedName of exposed properties needs to be cleared otherwise the clone will act as an instance
                var exposedRefs = clone.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(f => f.FieldType.IsGenericType && f.FieldType.GetGenericTypeDefinition() == typeof(ExposedReference <>)).ToList();
                foreach (FieldInfo fi in exposedRefs)
                {
                    var exposedRefInstance  = fi.GetValue(clone);
                    var exposedNameProperty = exposedRefInstance.GetType().GetField("exposedName");
                    if (exposedNameProperty != null)
                    {
                        var exposedNameValue = (PropertyName)exposedNameProperty.GetValue(exposedRefInstance);

                        bool isValid           = false;
                        var  originalReference = directorInstance.GetReferenceValue(exposedNameValue, out isValid);

                        if (isValid)
                        {
                            // generate new reference in directorInstance
                            var newPropertyName = new PropertyName(GUID.Generate().ToString());
                            directorInstance.SetReferenceValue(newPropertyName, originalReference);
                            exposedNameProperty.SetValue(exposedRefInstance, newPropertyName);

                            if (!EditorApplication.isPlaying)
                            {
                                EditorSceneManager.MarkSceneDirty(directorInstance.gameObject.scene);
                            }
                        }
                    }
                    fi.SetValue(clone, exposedRefInstance);
                }
            }

            return(clone);
        }
Esempio n. 4
0
        private static ScriptableObject CloneReferencedPlayableAsset(ScriptableObject original, PlayableDirector directorInstance)
        {
            ScriptableObject scriptableObject = Object.Instantiate <ScriptableObject>(original);

            if (scriptableObject == null || !(scriptableObject is IPlayableAsset))
            {
                throw new InvalidCastException("could not cast instantiated object into IPlayableAsset");
            }
            if (directorInstance != null)
            {
                SerializedObject   serializedObject  = new SerializedObject(original);
                SerializedObject   serializedObject2 = new SerializedObject(scriptableObject);
                SerializedProperty iterator          = serializedObject.GetIterator();
                if (iterator.Next(true))
                {
                    do
                    {
                        serializedObject2.CopyFromSerializedProperty(iterator);
                    }while (iterator.Next(false));
                }
                serializedObject2.ApplyModifiedProperties();
                EditorUtility.SetDirty(directorInstance);
            }
            if (directorInstance != null)
            {
                List <FieldInfo> list = (from f in scriptableObject.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                                         where f.FieldType.IsGenericType && f.FieldType.GetGenericTypeDefinition() == typeof(ExposedReference)
                                         select f).ToList <FieldInfo>();
                foreach (FieldInfo current in list)
                {
                    object    value = current.GetValue(scriptableObject);
                    FieldInfo field = value.GetType().GetField("exposedName");
                    if (field != null)
                    {
                        PropertyName propertyName   = (PropertyName)field.GetValue(value);
                        bool         flag           = false;
                        Object       referenceValue = directorInstance.GetReferenceValue(propertyName, ref flag);
                        if (flag)
                        {
                            PropertyName propertyName2 = new PropertyName(GUID.Generate().ToString());
                            directorInstance.SetReferenceValue(propertyName2, referenceValue);
                            field.SetValue(value, propertyName2);
                        }
                    }
                    current.SetValue(scriptableObject, value);
                }
            }
            IEnumerable <FieldInfo> enumerable = from f in scriptableObject.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                                                 where !f.IsNotSerialized && f.FieldType == typeof(AnimationClip)
                                                 select f;

            foreach (FieldInfo current2 in enumerable)
            {
                current2.SetValue(scriptableObject, TimelineHelpers.CloneAnimationClipIfRequired(current2.GetValue(scriptableObject) as AnimationClip, original));
            }
            return(scriptableObject);
        }
Esempio n. 5
0
        public void BindTimelineGlobal(PlayableDirector director)
        {
            foreach (var output in director.playableAsset.outputs)
            {
                if (!output.sourceObject || director.GetGenericBinding(output.sourceObject))
                {
                    continue;
                }
                GameObject go = PlayableManager.I.GetBindTarget(output.streamName);
                if (!go)
                {
                    continue;
                }
                if (output.outputTargetType.Equals(typeof(GameObject)))
                {
                    director.SetGenericBinding(output.sourceObject, go);
                }
                else
                {
                    var bind = go.GetComponent(output.outputTargetType);
                    director.SetGenericBinding(output.sourceObject, bind);
                }

                if (!(output.sourceObject is CinemachineTrack))
                {
                    continue;
                }
                var  cinemachineTrack = output.sourceObject as CinemachineTrack;
                bool b;
                foreach (var clip in cinemachineTrack.GetClips())
                {
                    var cinemachineShot = clip.asset as CinemachineShot;
                    if (director.GetReferenceValue(cinemachineShot.VirtualCamera.exposedName, out b))
                    {
                        continue;
                    }
                    GameObject go2 = PlayableManager.I.GetBindTarget(clip.displayName);
                    if (!go2)
                    {
                        continue;
                    }
                    var vc = go2.GetComponent <Cinemachine.CinemachineVirtualCameraBase>();
                    director.SetReferenceValue(cinemachineShot.VirtualCamera.exposedName, vc);
                }
            }
        }
    public static void DupTimeline()
    {
        // Fetch playable director, fetch timeline
        GameObject       playableDirectorObj = UnityEditor.Selection.activeObject as GameObject;
        PlayableDirector playableDirector    = playableDirectorObj.GetComponent <PlayableDirector>();
        TimelineAsset    timelineAsset       = playableDirector.playableAsset as TimelineAsset;

        // Duplicate
        string path    = AssetDatabase.GetAssetPath(timelineAsset);
        string newPath = path.Replace(".", "(Clone).");

        if (!AssetDatabase.CopyAsset(path, newPath))
        {
            if (showLogs)
            {
                Debug.LogError("Couldn't Clone Asset");
            }
            return;
        }

        // Copy Bindings
        TimelineAsset newTimelineAsset = AssetDatabase.LoadMainAssetAtPath(newPath) as TimelineAsset;

        PlayableBinding[] oldBindings = timelineAsset.outputs.ToArray();
        PlayableBinding[] newBindings = newTimelineAsset.outputs.ToArray();
        for (int i = 0; i < oldBindings.Length; i++)
        {
            playableDirector.playableAsset = timelineAsset;
            Object boundTo = playableDirector.GetGenericBinding(oldBindings[i].sourceObject);

            playableDirector.playableAsset = newTimelineAsset;
            playableDirector.SetGenericBinding(newBindings[i].sourceObject, boundTo);
        }

        // Copy Exposed References
        playableDirector.playableAsset = newTimelineAsset;
        foreach (TrackAsset newTrackAsset in newTimelineAsset.GetRootTracks())
        {
            foreach (TimelineClip newClip in newTrackAsset.GetClips())
            {
                foreach (FieldInfo fieldInfo in newClip.asset.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
                {
                    if (fieldInfo.FieldType.IsGenericType && fieldInfo.FieldType.GetGenericTypeDefinition() == typeof(ExposedReference <>))
                    {
                        // Fetch Old Exposed Name
                        object       exposedReference = fieldInfo.GetValue(newClip.asset);
                        PropertyName oldExposedName   = (PropertyName)fieldInfo.FieldType
                                                        .GetField("exposedName")
                                                        .GetValue(exposedReference);
                        bool isValid;

                        // Fetch Old Exposed Value
                        Object oldExposedValue = playableDirector.GetReferenceValue(oldExposedName, out isValid);
                        if (!isValid)
                        {
                            if (showLogs)
                            {
                                Debug.LogError("Failed to copy exposed references to duplicate timeline. Could not find: " + oldExposedName);
                            }
                            return;
                        }

                        // Replace exposedName on struct
                        PropertyName newExposedName = new PropertyName(UnityEditor.GUID.Generate().ToString());
                        fieldInfo.FieldType
                        .GetField("exposedName")
                        .SetValue(exposedReference, newExposedName);

                        // Set ExposedReference
                        fieldInfo.SetValue(newClip.asset, exposedReference);

                        // Set Reference on Playable Director
                        playableDirector.SetReferenceValue(newExposedName, oldExposedValue);
                    }
                }
            }
        }
    }