Atari800XL
Atari800XL

Reputation: 31

How to make keyframes in Blender 2.78a using Python?

I'm new to Blender and new to Python, on my Layer 1 I have a ball named "BallB".

Now I want to make a simple bubbling-animation using Python in Blender but I'm unable to make a keyframe. This should happen on Layer 2.

I tried many and got many errors... all the Snippets I found didn't work and my script allways crashed with Python-Errors like

RuntimeError: Operator bpy.ops.anim.change ... expected an timeline/animation area to be activated

and many more.

Has anybody some hints for me?

I'd like to learn scripted animations in Blender so I'm very thankful for every hint which advances me ;-)

My Code:

import bpy, math, random

d           = 4
anz         = 100
frameAnz    = 10

scene = bpy.context.scene
scene.frame_start = 1
scene.frame_end = 100


for anz in range (0,anz):

    ball = bpy.data.objects["ballB"]   

    tball = ball.copy()
    xpos = -1 * (d/2) + random.randint(0,(d-1))
    xpos += random.random()
    ypos = -1 * (d/2) + random.randint(0,(d-1))
    ypos += random.random()
    zpos =  random.randint(0,(d-1))
    zpos += random.random()



    bn = str(anz).zfill(5)
    bn = "zz_Ball-" + bn

    tball.name = bn
    tball.location = (xpos, ypos, zpos)
    sz = random.uniform(0.015,0.09)


    tball.scale = (sz,sz,sz)

    #tball.nodes["Emission"].inputs[1].default_value = 200
    tball.select = False
    scene.objects.link(tball)
    #print ("done!")

obj = bpy.context

for actFrame in range(1,frameAnz):
   # scene = bpy.context.scene
#    scene.keyframe_insert(data_path="gravity", frame = actFrame)


    for ob in scene.objects:

        ploc = ob.location
        #print (ploc)
        xpos = ploc[0]
        ypos = ploc[1]
        zpos = ploc[2]

        zpos = zpos + random.random()
        ob.location = (xpos, ypos, zpos)
        #ypos = ball.location[1]
        #zpos = ball.location]2]

        #zpos = zpos - random.random()

        #ball.location = (xpoy, ypos, zpos)
        #obj.keyframe_insert_menu('Location')
        #bpy.context.scene.frame_set(0)
    #scene = bpy.context.scene
    #scene.keyframe_insert(data_path="Location", frame=actFrame)

Actually it looks so:

enter image description here

Upvotes: 3

Views: 7497

Answers (1)

sambler
sambler

Reputation: 7079

You are close, you want to use obj.keyframe_insert(), using the index parameter you can keyframe just the one location value.

One issue you will have is that copying the initial object means the new object will use the same animation data, keeping them moving in unison. You can create a new object and use the same mesh data.

An objects layers property is an array of 20 booleans to specify where it is visible, when you add an object to a scene it will be set to be visible on the active layer, so set this after you link it to the scene.

import bpy, random

d           = 4
anz         = 100
frameAnz    = 20
scene = bpy.context.scene
scene.frame_start = 1
scene.frame_end = 100
ball = bpy.data.objects["ballB"]

for anz in range (0,anz):
    xpos = -1 * (d/2) + random.randint(0,(d-1))
    xpos += random.random()
    ypos = -1 * (d/2) + random.randint(0,(d-1))
    ypos += random.random()
    zpos =  random.randint(0,(d-1))
    zpos += random.random()

    bn = str(anz).zfill(5)
    bn = "zz_Ball-" + bn

    tball = bpy.data.objects.new(bn, ball.data)
    tball.location = (xpos, ypos, zpos)
    sz = random.uniform(0.015,0.09)
    tball.scale = (sz,sz,sz)

    tball.select = False
    scene.objects.link(tball)
    tball.layers = [False,True] + [False]*18

for actFrame in range(1,frameAnz):
    for ob in scene.objects:
        ob.location.z += random.random()
        ob.keyframe_insert(data_path='location', index=2, frame=actFrame)

Upvotes: 2

Related Questions