Exemplo n.º 1
0
 public static string GetTrackMenuName(System.Type trackType)
 {
     return(L10n.Tr(TypeUtility.GetDisplayName(trackType)));
 }
Exemplo n.º 2
0
        internal static void SetShowTrackMarkers(this TrackAsset track, bool showMarkers)
        {
            var currentValue = track.GetShowMarkers();

            if (currentValue != showMarkers)
            {
                TimelineUndo.PushUndo(TimelineWindow.instance.state.editSequence.viewModel, L10n.Tr("Toggle Show Markers"));
                track.SetShowMarkers(showMarkers);
                if (!showMarkers)
                {
                    foreach (var marker in track.GetMarkers())
                    {
                        SelectionManager.Remove(marker);
                    }
                }
            }
        }
Exemplo n.º 3
0
        internal static void AddTimeAreaMenuItems(GenericMenu menu, WindowState state)
        {
            foreach (var value in Enum.GetValues(typeof(TimelineAsset.DurationMode)))
            {
                var mode = (TimelineAsset.DurationMode)value;
                var item = EditorGUIUtility.TextContent(string.Format(TimelineWindow.Styles.DurationModeText, L10n.Tr(ObjectNames.NicifyVariableName(mode.ToString()))));

                if (state.recording || state.IsEditingASubTimeline() || state.editSequence.asset == null ||
                    state.editSequence.isReadOnly)
                {
                    menu.AddDisabledItem(item);
                }
                else
                {
                    menu.AddItem(item, state.editSequence.asset.durationMode == mode, () => SelectDurationCallback(state, mode));
                }

                menu.AddItem(DirectorStyles.showMarkersOnTimeline, state.showMarkerHeader, () => new ToggleShowMarkersOnTimeline().Execute(state));
            }
        }
Exemplo n.º 4
0
        internal static TrackAsset Duplicate(this TrackAsset track, IExposedPropertyTable sourceTable, IExposedPropertyTable destTable,
                                             TimelineAsset destinationTimeline = null)
        {
            if (track == null)
            {
                return(null);
            }

            // if the destination is us, clear to avoid bad parenting (case 919421)
            if (destinationTimeline == track.timelineAsset)
            {
                destinationTimeline = null;
            }

            var timelineParent = track.parent as TimelineAsset;
            var trackParent    = track.parent as TrackAsset;

            if (timelineParent == null && trackParent == null)
            {
                Debug.LogWarning("Cannot duplicate track because it is not parented to known type");
                return(null);
            }

            // Determine who the final parent is. If we are pasting into another track, it's always the timeline.
            //  Otherwise it's the original parent
            PlayableAsset finalParent = destinationTimeline != null ? destinationTimeline : track.parent;

            // grab the list of tracks to generate a name from (923360) to get the list of names
            // no need to do this part recursively
            var finalTrackParent   = finalParent as TrackAsset;
            var finalTimelineAsset = finalParent as TimelineAsset;
            var otherTracks        = (finalTimelineAsset != null) ? finalTimelineAsset.trackObjects : finalTrackParent.subTracksObjects;

            // Important to create the new objects before pushing the original undo, or redo breaks the
            //  sequence
            var newTrack = TimelineHelpers.Clone(finalParent, track, sourceTable, destTable, finalParent);

            newTrack.name = TimelineCreateUtilities.GenerateUniqueActorName(otherTracks, newTrack.name);

            RecursiveSubtrackClone(track, newTrack, sourceTable, destTable, finalParent);
            TimelineCreateUtilities.SaveAssetIntoObject(newTrack, finalParent);
            TimelineUndo.RegisterCreatedObjectUndo(newTrack, L10n.Tr("Duplicate"));
            UndoExtensions.RegisterPlayableAsset(finalParent, L10n.Tr("Duplicate"));

            if (destinationTimeline != null) // other timeline
            {
                destinationTimeline.AddTrackInternal(newTrack);
            }
            else if (timelineParent != null) // this timeline, no parent
            {
                ReparentTracks(new List <TrackAsset> {
                    newTrack
                }, timelineParent, timelineParent.GetRootTracks().Last(), false);
            }
            else // this timeline, with parent
            {
                trackParent.AddChild(newTrack);
            }

            // Call the custom editor. this check prevents the call when copying to the clipboard
            if (destinationTimeline == null || destinationTimeline == TimelineEditor.inspectedAsset)
            {
                var customEditor = CustomTimelineEditorCache.GetTrackEditor(newTrack);
                customEditor.OnCreate_Safe(newTrack, track);
            }

            return(newTrack);
        }
        public override void OnInspectorGUI()
        {
            if (target == null)
            {
                return;
            }

            serializedObject.Update();

            m_SourceObjectLabel.text = m_SourceObject.displayName;

            if (m_PrefabObject.objectReferenceValue != null)
            {
                m_SourceObjectLabel.text = L10n.Tr("Parent Object");
            }

            bool selfControlled = false;


            EditorGUI.BeginChangeCheck();

            using (new GUIMixedValueScope(m_SourceObject.hasMultipleDifferentValues))
                EditorGUILayout.PropertyField(m_SourceObject, m_SourceObjectLabel);

            var sourceGameObject = m_SourceObject.exposedReferenceValue as GameObject;

            selfControlled = m_PrefabObject.objectReferenceValue == null && TimelineWindow.instance != null && TimelineWindow.instance.state != null &&
                             contextDirector != null && sourceGameObject == contextDirector.gameObject;

            if (EditorGUI.EndChangeCheck())
            {
                CheckForCyclicReference();
                if (!selfControlled)
                {
                    DisablePlayOnAwake(sourceGameObject);
                }
            }

            if (selfControlled)
            {
                EditorGUILayout.HelpBox(L10n.Tr("The assigned GameObject references the same PlayableDirector component being controlled."), MessageType.Warning);
            }
            else if (m_CycleReference)
            {
                EditorGUILayout.HelpBox(L10n.Tr("The assigned GameObject contains a PlayableDirector component that results in a circular reference."), MessageType.Warning);
            }

            EditorGUI.indentLevel++;
            EditorGUILayout.PropertyField(m_PrefabObject, Styles.prefabContent);
            EditorGUI.indentLevel--;

            using (new EditorGUI.DisabledScope(selfControlled))
            {
                EditorGUILayout.PropertyField(m_UseActivation, selfControlled ? Styles.activationDisabledContent : Styles.activationContent);
                if (m_UseActivation.boolValue)
                {
                    EditorGUI.indentLevel++;
                    EditorGUILayout.PropertyField(m_PostPlayback, Styles.postPlayableContent);
                    EditorGUI.indentLevel--;
                }
            }

            m_SourceObject.isExpanded = EditorGUILayout.Foldout(m_SourceObject.isExpanded, Styles.advancedContent, true);

            if (m_SourceObject.isExpanded)
            {
                EditorGUI.indentLevel++;

                using (new EditorGUI.DisabledScope(selfControlled && !m_SearchHierarchy.boolValue))
                {
                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.PropertyField(m_UpdateDirector, selfControlled ? Styles.updatePlayableDirectorDisabledContent : Styles.updatePlayableDirectorContent);
                    if (EditorGUI.EndChangeCheck())
                    {
                        CheckForCyclicReference();
                    }
                }

                EditorGUILayout.PropertyField(m_UpdateParticle, Styles.updateParticleSystemsContent);
                if (m_UpdateParticle.boolValue)
                {
                    EditorGUI.indentLevel++;
                    EditorGUILayout.PropertyField(m_RandomSeed, Styles.randomSeedContent);
                    EditorGUI.indentLevel--;
                }
                EditorGUILayout.PropertyField(m_UpdateITimeControl, Styles.updateITimeControlContent);

                EditorGUILayout.PropertyField(m_SearchHierarchy, Styles.updateHierarchy);

                EditorGUI.indentLevel--;
            }

            serializedObject.ApplyModifiedProperties();
        }
Exemplo n.º 6
0
        void DrawNoSequenceGUI(WindowState windowState)
        {
            bool showCreateButton    = false;
            var  currentlySelectedGo = UnityEditor.Selection.activeObject != null ? UnityEditor.Selection.activeObject as GameObject : null;
            var  textContent         = DirectorStyles.noTimelineAssetSelected;
            var  existingDirector    = currentlySelectedGo != null?currentlySelectedGo.GetComponent <PlayableDirector>() : null;

            var existingAsset = existingDirector != null ? existingDirector.playableAsset : null;

            if (currentlySelectedGo != null && !TimelineUtility.IsPrefabOrAsset(currentlySelectedGo) && existingAsset == null)
            {
                showCreateButton = true;
                textContent      = new GUIContent(String.Format(DirectorStyles.createTimelineOnSelection.text, currentlySelectedGo.name, L10n.Tr("a Director component and a Timeline asset")));
            }
            GUILayout.FlexibleSpace();
            GUILayout.BeginVertical();
            GUILayout.FlexibleSpace();

            GUILayout.Label(textContent);

            if (showCreateButton)
            {
                GUILayout.BeginHorizontal();
                var textSize = GUI.skin.label.CalcSize(textContent);
                GUILayout.Space((textSize.x / 2.0f) - (WindowConstants.createButtonWidth / 2.0f));
                if (GUILayout.Button(L10n.Tr("Create"), GUILayout.Width(WindowConstants.createButtonWidth)))
                {
                    var message     = DirectorStyles.createNewTimelineText.text + " '" + currentlySelectedGo.name + "'";
                    var defaultName = currentlySelectedGo.name.EndsWith(DirectorStyles.newTimelineDefaultNameSuffix, StringComparison.OrdinalIgnoreCase)
                        ? currentlySelectedGo.name
                        : currentlySelectedGo.name + DirectorStyles.newTimelineDefaultNameSuffix;

                    // Use the project window path by default only if it's under the asset folder.
                    // Otherwise the saveFilePanel will reject the save (case 1289923)
                    var defaultPath = ProjectWindowUtil.GetActiveFolderPath();
                    if (!defaultPath.StartsWith("Assets/", StringComparison.OrdinalIgnoreCase))
                    {
                        defaultPath = "Assets";
                    }

                    string newSequencePath = EditorUtility.SaveFilePanelInProject(DirectorStyles.createNewTimelineText.text, defaultName, "playable", message, defaultPath);
                    if (!string.IsNullOrEmpty(newSequencePath))
                    {
                        var newAsset = TimelineUtility.CreateAndSaveTimelineAsset(newSequencePath);

                        Undo.IncrementCurrentGroup();

                        if (existingDirector == null)
                        {
                            existingDirector = Undo.AddComponent <PlayableDirector>(currentlySelectedGo);
                        }

                        existingDirector.playableAsset = newAsset;
                        SetTimeline(existingDirector);
                        windowState.previewMode = false;
                    }

                    // If we reach this point, the state of the panel has changed; skip the rest of this GUI phase
                    // Fixes: case 955831 - [OSX] NullReferenceException when creating a timeline on a selected object
                    GUIUtility.ExitGUI();
                }
                GUILayout.EndHorizontal();
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndVertical();
            GUILayout.FlexibleSpace();
        }
        public void Grab(IEnumerable <ITimelineItem> items, TrackAsset referenceTrack, Vector2 mousePosition)
        {
            if (items == null)
            {
                return;
            }

            items = items.ToArray(); // Cache enumeration result

            if (!items.Any())
            {
                return;
            }

            m_GrabbedModalUndoGroup = Undo.GetCurrentGroup();

            var trackItems      = items.GroupBy(c => c.parentTrack).ToArray();
            var trackItemsCount = trackItems.Length;
            var tracks          = items.Select(c => c.parentTrack).Where(x => x != null).Distinct();

            movingItems = new MovingItems[trackItemsCount];

            allowTrackSwitch = trackItemsCount == 1 && !trackItems.SelectMany(x => x).Any(x => x is MarkerItem); // For now, track switch is only supported when all items are on the same track and there are no items

            // one push per track handles all the clips on the track
            UndoExtensions.RegisterTracks(tracks, L10n.Tr("Move Items"));
            foreach (var sourceTrack in tracks)
            {
                // push all markers on the track because of ripple
                UndoExtensions.RegisterMarkers(sourceTrack.GetMarkers(), L10n.Tr("Move Items"));
            }

            for (var i = 0; i < trackItemsCount; ++i)
            {
                var track        = trackItems[i].Key;
                var grabbedItems = new MovingItems(m_State, track, trackItems[i].ToArray(), referenceTrack, mousePosition, allowTrackSwitch);
                movingItems[i] = grabbedItems;
            }

            m_LeftMostMovingItems  = null;
            m_RightMostMovingItems = null;

            foreach (var grabbedTrackItems in movingItems)
            {
                if (m_LeftMostMovingItems == null || m_LeftMostMovingItems.start > grabbedTrackItems.start)
                {
                    m_LeftMostMovingItems = grabbedTrackItems;
                }

                if (m_RightMostMovingItems == null || m_RightMostMovingItems.end < grabbedTrackItems.end)
                {
                    m_RightMostMovingItems = grabbedTrackItems;
                }
            }

            m_ItemGUIs   = new HashSet <TimelineItemGUI>();
            m_ItemsGroup = new ItemsGroup(items);

            foreach (var item in items)
            {
                m_ItemGUIs.Add(item.gui);
            }

            targetTrack = referenceTrack;

            EditMode.BeginMove(this);
            m_Grabbing = true;
        }
        public AnimationClip PrepareTrack(TrackAsset track, WindowState state, GameObject gameObject, out double startTime)
        {
            AnimationClip animationClip = null;

            // if we are not in clip mode, we simply use the track clip
            var animationTrack = (AnimationTrack)track;

            // ignore recording if we are in Legacy auto mode
            startTime = -1;
            var parentTrack = TimelineUtility.GetSceneReferenceTrack(track) as AnimationTrack;

            if (parentTrack != null && parentTrack.trackOffset == TrackOffset.Auto)
            {
                return(null);
            }

            if (!animationTrack.inClipMode)
            {
                var trackClip = animationTrack.GetOrCreateClip();
                startTime = trackClip.frameRate * state.editSequence.time;

                // Make the first key be at time 0 of the clip
                if (trackClip.empty)
                {
                    animationTrack.infiniteClipTimeOffset        = 0; // state.time;
                    animationTrack.infiniteClipPreExtrapolation  = TimelineClip.ClipExtrapolation.Hold;
                    animationTrack.infiniteClipPostExtrapolation = TimelineClip.ClipExtrapolation.Hold;
                }

                animationClip = trackClip;
            }
            else
            {
                TimelineClip activeClip = null;

                // if it fails, but returns no clip, we can add one.
                if (!track.FindRecordingClipAtTime(state.editSequence.time, out activeClip) && activeClip != null)
                {
                    return(null);
                }

                if (activeClip == null)
                {
                    activeClip = AddRecordableClip(track, state, state.editSequence.time);
                }

                var clip = activeClip.animationClip;

                // flags this as the clip being recorded for the track
                var clipTime = state.editSequence.time - activeClip.start;

                // if we are in the past
                if (clipTime < 0)
                {
                    Undo.RegisterCompleteObjectUndo(clip, L10n.Tr("Record Key"));
                    UndoExtensions.RegisterTrack(track, L10n.Tr("Prepend Key"));
                    ShiftAnimationClip(clip, (float)-clipTime);
                    activeClip.start     = state.editSequence.time;
                    activeClip.duration += -clipTime;
                    clipTime             = 0;
                }

                m_ClipTime         = clipTime;
                recordClip         = activeClip;
                startTime          = recordClip.ToLocalTimeUnbound(state.editSequence.time) * clip.frameRate;
                m_needRebuildRects = clip.empty;

                animationClip = clip;
            }

            m_TargetClip = animationClip;
            m_CurveCount = GetCurveCount(animationClip);
            m_TrackHasPreviewComponents = animationTrack.hasPreviewComponents;

            return(animationClip);
        }