0
$\begingroup$

I have this cube animation that moves at Z axis from Frame 1 to Frame 48.

enter image description here

I am trying to select a particular fcurve (Z location in this case) and trying to move a single keyframe from Frame 48 to Frame 62

import bpy

# Configuration
action_name = 'CubeAction'
data_path = 'location'
index = 2                # Z axis

# Find the appropriate action
action = bpy.data.actions.get(action_name)
if action:
    # From this action, retrieve the appropriate F-Curve
    fcurve = action.fcurves.find(data_path = data_path, index = index)
    if fcurve:
        for index in range(48, 63):
            fcurve.keyframe_points[index] += 2

But I am receiving an error below, what am I doing wrong?

Array iterator out of range: FCurve_keyframe_points_lookup_int (index 48)
Traceback (most recent call last):
  File "/Keyframe_mover.py", line 16, in <module>
IndexError: bpy_prop_collection[index]: index 48 out of range, size 2
Error: Python script failed, check the message in the system console

$\endgroup$
1
  • 1
    $\begingroup$ you try to access here: fcurve.keyframe_points[index] a keyframe point which obviously doesn't exist for index = 48 $\endgroup$
    – Chris
    Commented Mar 30, 2022 at 8:20

1 Answer 1

1
$\begingroup$

i think you misunderstood how the fcurves work:

check in the console:

 action.fcurves.find(data_path = 'location', index = 2).keyframe_points[1].co
result:    Vector((67.0, 4.13863468170166))

So Blender saves the keyframes in an array, where x is the frame number and y is the corresponding value (in this case the z location)

so if you have only two keyframes, the code should be like this:

import bpy

# Configuration
action_name = 'CubeAction.001'
data_path = 'location'
index = 2                # Z axis

# Find the appropriate action
action = bpy.data.actions.get(action_name)
if action:
    # From this action, retrieve the appropriate F-Curve
    fcurve = action.fcurves.find(data_path = data_path, index = index)
    if fcurve:
        
        fcurve.keyframe_points[1].co.x += 2
            
        print("changed")
    else:
        print("no fcurve")
else:
    print("no action")
    
print("end")

and by the way:

you should never use the same name (index) for different meanings - this is very bad coding and will make trouble.

You used index for the loop variable and for "z-axis" in line 6.

$\endgroup$
2
  • $\begingroup$ Thank you, this works. $\endgroup$ Commented Mar 30, 2022 at 10:17
  • 1
    $\begingroup$ You are welcome $\endgroup$
    – Chris
    Commented Mar 30, 2022 at 10:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .