123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Timeline;
- using UnityEngine.Playables;
- using UnityEngineInternal; // for metro type extensions
- namespace UnityEngine.Timeline
- {
- public partial class TimelineAsset
- {
- /// <summary>
- /// Allows you to create a track and add it to the Timeline.
- /// </summary>
- /// <param name="type">The type of track to create. Must derive from TrackAsset.</param>
- /// <param name="parent">Track to parent to. This can be null.</param>
- /// <param name="name">Name to give the track.</param>
- /// <returns>The created track.</returns>
- /// <remarks>
- /// This method will throw an InvalidOperationException if the parent is not valid. The parent can be any GroupTrack, or a supported parent type of track. For example, this can be used to create override tracks in AnimationTracks.
- /// </remarks>
- public TrackAsset CreateTrack(Type type, TrackAsset parent, string name)
- {
- if (parent != null && parent.timelineAsset != this)
- throw new InvalidOperationException("Addtrack cannot parent to a track not in the Timeline");
- if (!typeof(TrackAsset).IsAssignableFrom(type))
- throw new InvalidOperationException("Supplied type must be a track asset");
- if (parent != null)
- {
- if (!TimelineCreateUtilities.ValidateParentTrack(parent, type))
- throw new InvalidOperationException("Cannot assign a child of type " + type.Name + " to a parent of type " + parent.GetType().Name);
- }
- var actualParent = parent != null ? parent as PlayableAsset : this;
- TimelineUndo.PushUndo(actualParent, "Create Track");
- var baseName = name;
- if (string.IsNullOrEmpty(baseName))
- {
- baseName = type.Name;
- #if UNITY_EDITOR
- baseName = UnityEditor.ObjectNames.NicifyVariableName(baseName);
- #endif
- }
- var trackName = baseName;
- if (parent != null)
- trackName = TimelineCreateUtilities.GenerateUniqueActorName(parent.subTracksObjects, baseName);
- else
- trackName = TimelineCreateUtilities.GenerateUniqueActorName(trackObjects, baseName);
- TrackAsset newTrack = AllocateTrack(parent, trackName, type);
- if (newTrack != null)
- {
- newTrack.name = trackName;
- TimelineCreateUtilities.SaveAssetIntoObject(newTrack, actualParent);
- }
- return newTrack;
- }
- /// <summary>
- /// Creates a track and adds it to the Timeline Asset.
- /// </summary>
- /// <param name="parent">Track to parent to. This can be null.</param>
- /// <param name="trackName">The name of the track being created.</param>
- /// <typeparam name="T">The type of track being created. The track type must be derived from TrackAsset.</typeparam>
- /// <returns>Returns the created track.</returns>
- /// <remarks>
- /// This method will throw an InvalidOperationException if the parent is not valid. The parent can be any GroupTrack, or a supported parent type of track. For example, this can be used to create override tracks in AnimationTracks.
- /// </remarks>
- public T CreateTrack<T>(TrackAsset parent, string trackName) where T : TrackAsset, new()
- {
- return (T)CreateTrack(typeof(T), parent, trackName);
- }
- /// <summary>
- /// Creates a track and adds it to the Timeline Asset.
- /// </summary>
- /// <param name="trackName">The name of the track being created.</param>
- /// <typeparam name="T">The type of track being created. The track type must be derived from TrackAsset.</typeparam>
- /// <returns>Returns the created track.</returns>
- public T CreateTrack<T>(string trackName) where T : TrackAsset, new()
- {
- return (T)CreateTrack(typeof(T), null, trackName);
- }
- /// <summary>
- /// Creates a track and adds it to the Timeline Asset.
- /// </summary>
- /// <typeparam name="T">The type of track being created. The track type must be derived from TrackAsset.</typeparam>
- /// <returns>Returns the created track.</returns>
- public T CreateTrack<T>() where T : TrackAsset, new()
- {
- return (T)CreateTrack(typeof(T), null, null);
- }
- /// <summary>
- /// Delete a clip from this timeline.
- /// </summary>
- /// <param name="clip">The clip to delete.</param>
- /// <returns>Returns true if the removal was successful</returns>
- /// <remarks>
- /// This method will delete a clip and any assets owned by the clip.
- /// </remarks>
- public bool DeleteClip(TimelineClip clip)
- {
- if (clip == null || clip.parentTrack == null)
- {
- return false;
- }
- if (this != clip.parentTrack.timelineAsset)
- {
- Debug.LogError("Cannot delete a clip from this timeline");
- return false;
- }
- TimelineUndo.PushUndo(clip.parentTrack, "Delete Clip");
- if (clip.curves != null)
- {
- TimelineUndo.PushDestroyUndo(this, clip.parentTrack, clip.curves, "Delete Curves");
- }
- // handle wrapped assets
- if (clip.asset != null)
- {
- DeleteRecordedAnimation(clip);
- // TODO -- we should flag assets and owned, instead of this check...
- #if UNITY_EDITOR
- string path = UnityEditor.AssetDatabase.GetAssetPath(clip.asset);
- if (path == UnityEditor.AssetDatabase.GetAssetPath(this))
- #endif
- {
- TimelineUndo.PushDestroyUndo(this, clip.parentTrack, clip.asset, "Delete Clip Asset");
- }
- }
- var clipParentTrack = clip.parentTrack;
- clipParentTrack.RemoveClip(clip);
- clipParentTrack.CalculateExtrapolationTimes();
- return true;
- }
- /// <summary>
- /// Deletes a track from a timeline, including all clips and subtracks.
- /// </summary>
- /// <param name="track">The track to delete. It must be owned by this Timeline.</param>
- /// <returns>True if the track was deleted successfully.</returns>
- public bool DeleteTrack(TrackAsset track)
- {
- if (track.timelineAsset != this)
- return false;
- // push before we modify properties
- TimelineUndo.PushUndo(track, "Delete Track");
- TimelineUndo.PushUndo(this, "Delete Track");
- TrackAsset parent = track.parent as TrackAsset;
- if (parent != null)
- TimelineUndo.PushUndo(parent, "Delete Track");
- var children = track.GetChildTracks();
- foreach (var child in children)
- {
- DeleteTrack(child);
- }
- DeleteRecordedAnimation(track);
- var clipsToDelete = new List<TimelineClip>(track.clips);
- foreach (var clip in clipsToDelete)
- {
- DeleteClip(clip);
- }
- RemoveTrack(track);
- TimelineUndo.PushDestroyUndo(this, this, track, "Delete Track");
- return true;
- }
- internal void MoveLastTrackBefore(TrackAsset asset)
- {
- if (m_Tracks == null || m_Tracks.Count < 2 || asset == null)
- return;
- var lastTrack = m_Tracks[m_Tracks.Count - 1];
- if (lastTrack == asset)
- return;
- for (int i = 0; i < m_Tracks.Count - 1; i++)
- {
- if (m_Tracks[i] == asset)
- {
- for (int j = m_Tracks.Count - 1; j > i; j--)
- m_Tracks[j] = m_Tracks[j - 1];
- m_Tracks[i] = lastTrack;
- Invalidate();
- break;
- }
- }
- }
- internal TrackAsset AllocateTrack(TrackAsset trackAssetParent, string trackName, Type trackType)
- {
- if (trackAssetParent != null && trackAssetParent.timelineAsset != this)
- throw new InvalidOperationException("Addtrack cannot parent to a track not in the Timeline");
- if (!typeof(TrackAsset).IsAssignableFrom(trackType))
- throw new InvalidOperationException("Supplied type must be a track asset");
- var asset = (TrackAsset)CreateInstance(trackType);
- asset.name = trackName;
- if (trackAssetParent != null)
- trackAssetParent.AddChild(asset);
- else
- AddTrackInternal(asset);
- return asset;
- }
- void DeleteRecordedAnimation(TrackAsset track)
- {
- var animTrack = track as AnimationTrack;
- if (animTrack != null && animTrack.infiniteClip != null)
- TimelineUndo.PushDestroyUndo(this, track, animTrack.infiniteClip, "Delete Track");
- if (track.curves != null)
- TimelineUndo.PushDestroyUndo(this, track, track.curves, "Delete Track Parameters");
- }
- void DeleteRecordedAnimation(TimelineClip clip)
- {
- if (clip == null)
- return;
- if (clip.curves != null)
- TimelineUndo.PushDestroyUndo(this, clip.parentTrack, clip.curves, "Delete Clip Parameters");
- if (!clip.recordable)
- return;
- AnimationPlayableAsset asset = clip.asset as AnimationPlayableAsset;
- if (asset == null || asset.clip == null)
- return;
- TimelineUndo.PushDestroyUndo(this, asset, asset.clip, "Delete Recording");
- }
- }
- }
|