[Script]Nudge Keyframe

I sure hope I’m not posting something that is already out there.
In 3ds Max I found a script a long time a go,that was called “add inbetween” .In reality it just added a frame to the timeline.I thought it was useless but once I started adopting the “blocking” stage,I found it quite useful.When I started using blender,I felt that i was with my hands tied because I did not had that script.Looked for something similar for Blender,but at that time did not found it.So I decided to learn Python and script it myself.So here it is:

GitHub <–Download
Gumroad <–Download

The panel is located in the Dope Sheet, in the ‘n’ menu

v.0.4.0 -----------------------------------------------------

Add/modify inbetween

  • Adds a keyframe between two keyframes with input for frame: half of the distance between the first and the second keyframe.And input for value: a value between the value of keyframe 1 and keyframe 2.

If there is no selected keyframes it will create the keyframe based on what percentage we give it.
If there is one selected keyframe it will modify that keyframe based on time position(current frame).
One side effect of the way I have it now is that …while you cannot see the result,you could have a keyframe selected,but have your timeline(current frame) someplace else…then the value input will be taken from the keyframes where the timeline is at. So…you could do a blend between some other keyframes.

Known issues :

  • when created the keyframes have different appearence than normal keyframes. I will look in to that.
  • in 7.9 moving the slider updates the graph editor,but not the viewport. At least on my end.

v.0.3.6 -----------------------------------------------------

Fixes of issues

  • Come over now work with multiple objects selected.It retains the global order of keyframes.For example you have obj1-keyframes on 2,4,6,8 and obj2- 3,5,9. Then we select 4 as our first keyframe.Running the “Come over” script will move obj1-frames 4,6,8 and obj2, 5,9
  • “Hold for” same fix.In the above example let’s say we select keyframes 2,4,6 in obj1 and set the Hold for 4 frames.This will create 4 frames difference between the global positions.In other words the distance between keyframe 2 in obj1 and keyframe 3 in obj2 will be 4 frames,and so on.Note that this will lead to the distance between keyframe 2 in obj1 and keyframe 4 in obj1 to be 8 frames not 4.On the other hand keyframe 4 obj1 will be 4 frames away from keyframe 3 obj2.


Fixes of issues:

  • the fcurve issue: scripts “push/pull”,“hold for” did not work when we had different keyframe numbers in the fcurves than first curve.This is now fixed,and it does not matter how many or where the keyframes are.They will now behave as you would expect.I removed the “if fcurve visible” condition in the “come over” script.
  • when just checking something, I noticed that the “come over” script was failing when we have multiple selected keyframes.If the first fcurve had less keys than the others,it would take that first key and use it as the “come over” origin and move all keyframes afterwards to the “target”(timeline position).So thanks to what I learned during the fix of the “push/pull”,“hold for” scripts…I was able to fix that as well.

Blender 2.8 migration:

  • Few days a go I went in and looked how to make the scripts working in 2.8.After some research I managed to bring it to 2.8 and uploaded the file.I haven’t mentioned it here.I wanted it to be part of this update.However when I started blender 2.8 today, and imported the new scripts,it was not loading.I tried the old version that I got working back then, and yet still I got the same error:
  •   \addon_utils.py", line 331, in enable
      mod = __import__(module_name)
      ModuleNotFoundError: No module named 'Keyframe_Nudge 2'
  • if anyone knows why it gives me this error I will be grateful if you can comment.Otherwise I will have to figure it our on my own,and until then no 2.8 version. Maybe it will work for you guys.So you can always give it a try.


I was trying to figure out the issue with the fcurves,somewhere along the way I managed to actually do the “Comve Over Here” script:
Come Over

  • This one is not driven by the number in that input in the middle,but firstly by the current frame position,and second by a selected keyframe.
  • It pushes the selected keyframe and all following keyframes to the current frame position.
  • one issue is that since it is selection driven,if you don’t have a selection it will give you that annoying popup error message.
  • At the moment the script has a line that makes the script work only on visible fcurves. Maybe I’ll remove this in the future.

Issue fixes:

  • as I said, I set out to figure out the fcurve issue and I did manage to figure it out.At the moment only the Come Over function has this in it.But I will rewrite the Push/Pull and the Hold for functions to adopt this fix.


UI change of the panel:

  • the user now has the ability to chose his custom number for the functions.
  • all functions in the panel are driven by one user input field
  • the input is limited to 1min and 24 max.

Insert Empty frame is now called Push Pull:

  • Before this was possible only based on timeline position,and not selection.Now it prefers selection and then if there is no selection it will use the timeline.

Nudge Keyframe:

  • rewrote the script function to avoid possible overwriting of keyframes.Maybe it was pointless since the selected keyframes appear to behave as if on another layer(and nudge is only selected keyframe driven)

Set On function,named Hold for:

  • I decided to change the name to Hold for,because that’s what it really does if you look it from a stepped keyframe tangent…it holds that keyframe for x frames.
  • it works with one key selected,as well as groups of keys selected.
  • NOTE : I have not tested it but I suppose it won’t work with pattern selected keyframes.Or to be more clear…if we have keyframes at 2,4,6,8,10,12,14 and we select keyframes 4,6 and 12 and want those to be on 4’s,I suppose it will not care for the gap and keyframes at 4 and 6 will get mixed with 8 and 10 or will overwrite them.So I suppose at the moment the procedure is to just select the keyframes or groups of keyframes that you want to set on the same “Hold” ,one at a time ,instead of selecting a patter of keyframes.

Known Issues:

  • If one or more of your fcurves does not have the same amount keyframes as the first,it will crash the script and it will stop after the first or the last fcurve that has the same keyframe number in them.If you like to have a key on every keyframe it should not be a issue.But even though I prefer this method of animation…at times I like to delete a keyframe from a specific channel and let the computer do his smooth tween.So it is something I want to fix…but at the moment I have no idea how.
  • also the scripts don’t regard selected or visible fcurve…so working on one fcurve will result in changes throughout all fcurves.

Ideas for development:

  • Come over here! - function,where it pushes or pulls keyframes to the current timeline position.Maybe it should be selection driven,like one or first keyframe in a list?
  • Caged Nudge - nudge a keyframe or group of keyframes but make it impossible for them to go on top,or jump over the previous or next not selected keyframe,depending on movement.


Insert Empty Frame : is dependent on the current frame,so it will move all keyframes from that frame to the end of the timeline.Basically doing the select right function.And setting a new keyframe position for every key in the selection.In Max the script was made to do the same thing as add inbewteen in maya(note it adds just an empty frame,not a real inbetween as a 50% if previous and next keyframe)

Nudge Frame : does what it says,moves the keyframe based on the button(value) given. And it’s selection dependent so if you have no keyframes selected it will not do anything.

Hope you find them useful .

I pan on fixing the panel a bit.If I can figure out hot to add an input field and just have ‘+’ and ‘-’ buttons to run the command based on the user input.
Another thing I plan is the ‘set on X frames’ feature.Basically making the distance between the selected keyframes equal to X.Like if we say: Set on 2’s.The selected keyframes will be on 2’s.I think I have the code figured out in my head…I just hope it works in practice.


Thanks, it looks interesting.

I have found an issue that goes against the concept I have for the scripts,i.e. that the script will change the timing of the keyframes the user has,but keep the pattern.In other words if the user has keyframes on one fcurve in one frame but does not have a keyframe in that frame position in another fcurve this pattern should be preserved.

And right now the script does that,but only for one object.Basically the script knows the pattern of the keyframes only for one object at a time.
But what happens when we have multiple objects(controllers) that for one reason or another don’t all have keyframes on the same frames that we want to manipulate?Well I expect that this pattern will be modified.I haven’t tested it,since I came to this conclusion while animating in max,because somehow I ended up having keyframes on one object(controller) and no keyframes in another and things worked and I did not wanted to go in an add more keys because of time limitations.
So my asumption is that the “push and pull”, and “nudge” will be fine. But the “come over” and “hold for” scripts will brake that keyframe pattern.
I think the solution is simple -basically bring the variables that store the keyframe data outside the " for object in selected objects" loop. But I guess I have to put time to do that, and test it.So at the moment anyone using the script should be aware of the possible issue.
If you always key all controllers for every keyframeyou have,most likely you won’t have this issue.But if somehow you forgotten then it will brake your pattern.
For “come over” there is a work around and that is to add a keyframe for all objects at the first selected keyframe.Since the script uses the first selected keyframe to calculate the distance to the “current frame”.

1 Like

Updated the scripts I wanted to redo “Come Over” and “Hold For”.
They now respect the global keyframe position of all selected objects.I will add a gif soon for better explenation.

Note, that selecting only one object will affect only that object’s keyframes and not all objects in the scene…Makes sense but still to say it.You need to select all objects(controllers) to modify the other objects(controllers) timing.

Something I did not expected to happen,but in the end I coded it that way.But now you don’t need to select all the keyframes you want to modify(for the “Hold For”).Just the first and the last in the group of keyframes. Of course selecting all them also works.

I added a gumroad page.If after some time,you end up enjoying the scripts,I added this feature so you can say thank you in a more impactful way.But it’s free anyway.Also I archived the files so people might prefer that method of downloading than going to GitHub. Being a non programmer I know I hated GitHub links.

1 Like

Started with just a simple exploration.Ended up with add inbetween.
Basically creates a keyframe in halfway point between two keyframes,based on the timeline position.If a keyframe is already selected(or after the creation) and the timeline is on the keyframe you can real time update the value by moving the slider.Thus you could create some kind of a blend towards one or the other value of the frame before and after the created keyframe(or the timeline position).
I could say that this is v0.1 of this script.I have some ideas: like to see if we have 2 keyframes selected. Then instead of modifying the values of these frames…to modify the value of the keyframe at the timeline position based on those two values.
Also when we have 1 keyframe selected…right now it uses the timeline to get the previous or next keyframes.This could lead to interesting effects but I want this to be left to the “if 2 keyframes selected” functionality.Thus make sure that if we have 1 keyframe…it will blend only between it’s previous and next keyframes.
By the way…it’s a bit unclear from the gif I made.But if you don’t have a keyframe selected,you don’t need to be on the halfway point to create it.It will be created automatically there and the timeline(current frame) will be moved automatically to that frame.

today i was trying the inbetween.And found one limitation and that is that if you are editing the key(updating it’s value),or adding a new key(creating the inbetween). It will be created or modified in all fcurves for the object.While when creating this might be your decision.When I was trying to use the script I found that I wanted the script to apply the changes only to one fcurve keyframe,and not all.So I went in and added a condition check to see if the fcurve that will be modified is visible.One has few options from the API - is the fcurve hidden,selected,or locked. So I figured that selected would make sense…but this means that you have to pre-select all the curves you want to modify.Also when creating a new keyframe,usually none of the fcurves are selected. So right now…if you want to edit separate fcurves with the inbetween slider…you will have to hide all the other fcurves.
Note: if you isolate and modify let’s say Xfcurve and then isolate and modify Zcurve(for example).If you then have them both visible or all visible then using the slider will give them all the same proportion.In other words…it will remove any difference like: on Xfcurve the keyframe was closer to previous keyframe,and on Zfcurve the keyframe was closer to next keyframe…If you have them both visible then applying the slider will cause them to get at the same precentage of distance.

Nice idea. Thanks


  • I have managed to fix some things that bugged me.Like the fact that the script did not retain the pattern in the y value of keyframes.Like if the Z-fcurve keyframe is more closer to B than X-fcurve keyframe. But unfortunately,to have comfortable control of this blender’s slider widget have to reset back to some value when it is released by the mouse drag.However Blender devs, have not considered to allow users to work with a button or slider’s -press/release states so we can fire commands when we have those states.Thus at the moment development on this is stopped.I made a workaround…which is kind of OK but no doubt the user might find it awkward …so I won’t be posting that as well.I’m looking in to building my own ui using the bgl module and OpenGL.But at the moment I have no idea how to do anything.

A bit of an update:

  • Things with the idea of making an custom ui is taking more than I expected and I have no idea how longer will this take. Not because I lack knowledge on how to do it. But the bgl module is not working the way I would expect it to be working. Either I’m not doing something right or the module has issues when you interact with it directly. Otherwise I can do pretty much everything I need in pyOpenGL,so it’snot a matter of me wondering how to do it.
  • Lately I’ve been working with grease pencil, doing storyboards. Mainly I use Krita but at times I switch to Blender. And I really felt a need to have the scripts from Keyframe Nudge work with Grease Pencil. So…I finally put some time off and reworked the push/pull script and made a blender UI panel for it as well.
    Eventually when I manage to have bgl working,I’ll just make a toggle for it, in the panel I plan to work on. And I was thinking that another option is to have the script work for both object keyframes(scale,rotation,translation) and grease pencil keyframes(layer keyframes).So we won’t be switching between the two when we push around keyframes for GP objects.
    Anyway here is the Grease Nudge repository link :