Can't create Animation Clip and set keys with code "No animation clip assigned"

I’m trying to create animation clips and set keys with c#. @seant_unity helped me out here to set curves on a custom clip but the same approach doesn’t work for animation clips. I’m using 2018.3.0f2

In the image below you can see the “My Animation Clip” has been created in the timeline. I recorded a clip “Recorded” and you can see the Position.y keys

However when I open My Animation Clip the position x,y,z keys are not available in the track header even though the y keys I created via c# are in the clip/not a clip. :hushed:

I feel it may have something to do with the Animation Playable Asset but I’ve not been able to find much info on this.

Here is my code:

            var playableDirectors = FindObjectsOfType<PlayableDirector>();
            foreach (var director in playableDirectors)
            {
                var timelineAsset = director.playableAsset as TimelineAsset;
                if (timelineAsset != null)
                {
                    foreach (var track in timelineAsset.GetOutputTracks())
                    {
                        if (track.name == "Sprite Test Track")
                        {
                            var newCustomClip = track.CreateClip<SpriteTestClip>();
                            newCustomClip.displayName = "My New Clip";
                            newCustomClip.duration = 10;
                        }

                        if (track.name == "Animation Track")
                        {
                            var newCustomClip = track.CreateDefaultClip();
                            newCustomClip.displayName = "My Animation Clip";
                            newCustomClip.duration = 10;

                            Keyframe[] keys;
                            keys = new Keyframe[3];
                            keys[0] = new Keyframe(0.0f, 0.0f);
                            keys[1] = new Keyframe(1.1f, 1.5f);
                            keys[2] = new Keyframe(2.0f, 0.0f);
                            curve = new AnimationCurve(keys);
                            Debug.Log(curve.keys[1].time);

                            typeof(TimelineClip).GetMethod("AllocateAnimatedParameterCurves", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(newCustomClip, new object[] { });
                            newCustomClip.curves.SetCurve("", typeof(AnimationClip), "Position.y", curve);

                            AssetDatabase.SaveAssets();

                            // This is just me thowing mud at a wall - I have no idea what I am doing
                            AnimationPlayableAsset animationPlayableAsset = newCustomClip.asset as AnimationPlayableAsset;
                            animationPlayableAsset.clip = newCustomClip.animationClip;

                        }

                    }
                }
            }

Any advice would be greatly appreciated. Cheers

Update: The transform issue was solved - I was stupidly not using Transform localPosition when setting the curve

                            typeof(TimelineClip).GetMethod("AllocateAnimatedParameterCurves", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(newCustomClip, new object[] { });
                            newCustomClip.curves.SetCurve("", typeof(Transform), "localPosition.y", curve);

Update: So it appears I am creating the clip but it is not saving. I can see that the Recorded clip is a child asset of the timeline - but My Animation Clip - even though it is on the timeline is not yet a child asset

4230637--376240--NoClipAssigned4.png

I’m guessing it will be related to something like this

AnimationClip animclip = newCustomClip.animationClip;
AnimationPlayableAsset animationPlayableAsset = newCustomClip.asset as AnimationPlayableAsset;
animationPlayableAsset.clip = animclip;

I tried generating an UnityEngine.AnimationClip and while that worked I can’t edit the curves in the Timeline - so I need to get a UnityTimeline.AnimationClip.

Cheers

Update: I’m also seeing this error but I’m not sure if it is related.

TreeView root item is null. Ensure that your TreeViewDataSource sets up at least a root item.
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

For animation tracks clips, you can use CreateRecordableClip(). It will create blank animation clips ready for timeline to record with…or you can modify it yourself. The clip will be available via animationPlayableAsset.clip (like in your example).

That method will add it to the asset database (make sure your timeline is in the asset database first) and set the clip to be recordable - which makes it show up in the curve editor.

@seant_unity thanks very much.

Is there a way to make the new clip start at the end of the previous clip (if any). When CreateDefaultClip() is used it adds the new clip to the end of the previous clip (if any). I see that with CreateRecordableClip() I must specify the start time.

Please know that, in my mind at least, you are a living legend.

Cheers

theAnimationTrack = timelineAsset.GetOutputTrack(0) as AnimationTrack;
theAnimationClip = theAnimationTrack.CreateRecordableClip("MyRecordableClip");
theAnimationClip.duration = 10;

theAnimationClip.start = 10;

AnimationPlayableAsset animationPlayableAsset = theAnimationClip.asset as AnimationPlayableAsset;

Keyframe[] keys;
keys = new Keyframe[3];
keys[0] = new Keyframe(0.0f, 0.0f);
keys[1] = new Keyframe(1.1f, 1.5f);
keys[2] = new Keyframe(2.0f, 0.0f);
curve = new AnimationCurve(keys);

typeof(TimelineClip).GetMethod("AllocateAnimatedParameterCurves", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(theAnimationClip, new object[] { });
animationPlayableAsset.clip.SetCurve("", typeof(Transform), "localPosition.y", curve);

AssetDatabase.SaveAssets();
AssetDatabase.Refresh();

Ah, thanks for pointing that out - we didn’t realize the behavior was different.

I think the simplest workaround is assign the duration of the track.
var d = track.duration;
var c = track.CreateRecordableClip(…);
c.start = d;

And thanks for the kind words, over the top as they might be. They are another gentle reminder that Unity has such a positive and amazing community :slight_smile: