// Gets the appropriate track for a given game object static TrackAsset GetTrackForGameObject(GameObject gameObject, WindowState state) { if (gameObject == null) { return(null); } var director = state.editSequence.director; if (director == null) { return(null); } var level = int.MaxValue; TrackAsset result = null; // search the output tracks var outputTracks = state.editSequence.asset.flattenedTracks; foreach (var track in outputTracks) { if (track.GetType() != typeof(AnimationTrack)) { continue; } if (!state.IsTrackRecordable(track)) { continue; } var obj = TimelineUtility.GetSceneGameObject(director, track); if (obj != null) { // checks if the effected gameobject is our child var childLevel = GetChildLevel(obj, gameObject); if (childLevel != -1 && childLevel < level) { result = track; level = childLevel; } } } // the resulting track is not armed. checking here avoids accidentally recording objects with their own // tracks if (result && !state.IsTrackRecordable(result)) { result = null; } return(result); }
public static IEnumerable <GameObject> GetRecordableGameObjects(WindowState state) { if (state == null || state.editSequence.asset == null || state.editSequence.director == null) { yield break; } var outputTracks = state.editSequence.asset.GetOutputTracks(); foreach (var track in outputTracks) { if (track.GetType() != typeof(AnimationTrack)) { continue; } if (!state.IsTrackRecordable(track) && !track.GetChildTracks().Any(state.IsTrackRecordable)) { continue; } var obj = TimelineUtility.GetSceneGameObject(state.editSequence.director, track); if (obj != null) { yield return(obj); } } }
// Helper that finds the animation clip we are recording and the relative time to that clip static bool GetClipAndRelativeTime(UnityEngine.Object target, WindowState state, out AnimationClip outClip, out double keyTime, out bool keyInRange) { const float floatToDoubleError = 0.00001f; outClip = null; keyTime = 0; keyInRange = false; double startTime = 0; double timeScale = 1; AnimationClip clip = null; IPlayableAsset playableAsset = target as IPlayableAsset; Component component = target as Component; // Handle recordable playable assets if (playableAsset != null) { var curvesOwner = AnimatedParameterUtility.ToCurvesOwner(playableAsset, state.editSequence.asset); if (curvesOwner != null && state.IsTrackRecordable(curvesOwner.targetTrack)) { if (curvesOwner.curves == null) { curvesOwner.CreateCurves(curvesOwner.GetUniqueRecordedClipName()); } clip = curvesOwner.curves; var timelineClip = curvesOwner as TimelineClip; if (timelineClip != null) { startTime = timelineClip.start; timeScale = timelineClip.timeScale; } } } // Handle recording components, including infinite clip else if (component != null) { var asset = GetTrackForGameObject(component.gameObject, state); if (asset != null) { clip = GetRecordingClip(asset, state, out startTime, out timeScale); } } if (clip == null) { return(false); } keyTime = (state.editSequence.time - startTime) * timeScale; outClip = clip; keyInRange = keyTime >= 0 && keyTime <= (clip.length * timeScale + floatToDoubleError); return(true); }
static bool ProcessPlayableAssetModification(UndoPropertyModification mod, WindowState state) { var target = GetTarget(mod) as IPlayableAsset; if (target == null) { return(false); } var curvesOwner = AnimatedParameterUtility.ToCurvesOwner(target, state.editSequence.asset); if (curvesOwner == null || !state.IsTrackRecordable(curvesOwner.targetTrack)) { return(false); } return(ProcessPlayableAssetRecording(mod, state, curvesOwner)); }