Offset Keyframe Animation (Auto-Stagger)

On 17/07/2017 at 07:28, xxxxxxxx wrote:

Hi @all!

I want to offset a keyframe animation over 20 animation tracks in one object. I found some old threads in this and other forums, but none of them seems to deal with the problem I'm facing - although I find it not very special.

What I'm trying to do (animated UserData in one object) :


all keyframes have been selected and the offset of 15 frames is set.
After that, some keyframes have been selected and the offset of -13 has been chosen.

With that, you get a staggered animation with different speeds.

I tried to come to a solution via the SDK, but.. well the simple answer is I'm not a good programmer, so I got stuck quite quickly. ;-) It seems that a selected object is always needed and I cannot access the keyframes from the UserData.

Maybe someone here can help me. I'm even quite sure there was a plugin somewhere, but I can't find it anywhere.

C4D Version: R18

you get the same effect by selecting all the keyframes and in the "Keytime.... [     ]"-Field you type in: x+(floor(num/7)*15)

7 being the number of selected keyframes in one timeline
15 being the keyframeoffset

somehow this is a bit buggy and some keyframes are not moved._

On 18/07/2017 at 02:47, xxxxxxxx wrote:


I haven't actually understood, what the actual issue or bug is.
So here are a few basic classes, that should get you going:

First of all, you need the DescID(s) of the animated User Data parameter(s). This can be constructed quite easily, note the ID given from the User Data Manager, I'll call UDID here. The UDID is stored in the second level of a DescID, with the first level marking it as a User Data, for example like so:

id = c4d.DescID(c4d.DescLevel(c4d.ID_USERDATA), c4d.DescLevel( UDID )) # replace UDID with ID of User Data

The keyframes (CKey) are stored in curves (CCurve), which themselves are stored in tracks (CTrack). You can get hold of the CTrack with FindCTrack() (for any entity, not only a selected object) and the above constructed DescID. Via GetCurve() you get the CCurve and from this finally the CKey with for example GetKey(). Or you can directly move them in time with MoveKey().

Note, time is handled as BaseTime.

With this it should be quite easy to iterate over all relevant keys and move them as needed.

In our C++ docs we have some manuals, which provide a bit more context and are generally also recommended to Python developers:
DescID Manual
DynamicDescription Manual (User Data)
Animation Overview and Manuals
BaseTime Manual