6
$\begingroup$

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 thankfull 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: Screenshot Blender

$\endgroup$
1

1 Answer 1

4
$\begingroup$

Finally I found a solution which works great for me. I added some commits so others with the same starter problems can use it.

Remember: there must be an named object defined in originName, otherwise the script will crash!

import bpy, math, random


d           = 4           # size of area where the balls spawn (STRG+Q to see what I mean)
anz         = 100           # number of balls
frameAnz    = 100           # number of generated frames
spawnScale = [0.015 , 0.09] # range for random scale during spawnprocess of a new ball
originName = "motherBall"   # name of the origin-object

#prepare scene, keyframes and keyframe-pointer:
scene = bpy.context.scene
scene.frame_start = 0
scene.frame_end   = frameAnz
bpy.ops.screen.frame_jump(end=False)

# first remove all objects from previous script-runs:
# (better than "a", then "x" and then ENTER before restarting this script!)
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

# "pick" the original ball from layer 1:
oBall = bpy.data.objects[originName]  

# loop for creating (anz)x balls:
for anz in range (0,anz):

    # duplicate the original ball and
    # name the new ball like "zz_Ball-00001"  
    # zz_ is for standing below in the outliner
    newBall = oBall.copy()
    newBallName = str(anz).zfill(5)
    newBallName = "zz_Ball-" + newBallName
    newBall.name = newBallName

    # now generate a random position for the new ball:
    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()
    # and place the new ball at this:
    newBall.location = (xpos, ypos, zpos)

    # scaling the new ball to get different sizes of balls:
    sz = random.uniform(spawnScale[0] , spawnScale[1])
    newBall.scale = (sz,sz,sz)

    #finally deselect the ball and link it into the scene:
    newBall.select = False
    scene.objects.link(newBall)

# now lets create frame by frame:
for actFrame in range(1,frameAnz + 1):

    bpy.context.scene.frame_set(actFrame)
    for ob in scene.objects:

        if (ob.name != originName):
            ploc = ob.location
            xpos = ploc[0]
            ypos = ploc[1]
            zpos = ploc[2]

            zpos = zpos + ( random.random() / 8)
            ob.location = (xpos, ypos, zpos)
            ob.keyframe_insert(data_path="location", index=-1)

# job done: now reset the framekeypointer to 0    
bpy.ops.screen.frame_jump(end=False)
$\endgroup$
7
  • $\begingroup$ not work, how can change originName $\endgroup$
    – saded
    Commented Jan 12, 2017 at 18:22
  • $\begingroup$ Look in your outliner for the name of your objects. If its f.e. "foobazbar" then replace "motherBall" for "foobazbar" in line 7. Also enable the python-console by clicking "toggle system console" under the dropdown window - there you can see if any other erros appear. $\endgroup$
    – Atari800XL
    Commented Jan 13, 2017 at 5:31
  • $\begingroup$ I change but i have other error in line :oBall = bpy.data.objects[originName] , in console: Foobazbar not founed $\endgroup$
    – saded
    Commented Jan 13, 2017 at 9:46
  • $\begingroup$ Here, take my .blend and compare the variable in line 8 to the outliner on the right side, both names must be equal otherwise the script can't copy this origin object. filedropper.com/gravity $\endgroup$
    – Atari800XL
    Commented Jan 14, 2017 at 19:08
  • $\begingroup$ Good it work, than you $\endgroup$
    – saded
    Commented Jan 15, 2017 at 11:07

You must log in to answer this question.

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