Procedural spider animation + .Blend!

Got my Spider rig working :smiley:

You may have seen from my other posts that I have been working on a StepConstraint for a Spider Rig, I have since realized that their is more to making a spider than I first thought:o and a simple constraint is not enough to solve the problem. So I have been working on a full fledged Script to control a Spider/Insect with adaptive step distance and height control.

So you want to see where I’m up to:

I have noticed some poping on the legs >= LegCount/2, any Ideas?

And here is the .Blend :smiley:


import Blender,BPyWindow,BPyMesh,bpy
import math
from Blender import *
from Blender.Scene import *
from Blender.NMesh import *
from Blender.Window import *
from Blender.Mathutils import *

MaxDist = 4.000
SpiderLeg = 'SpiderLeg'
MasterName = 'Master'
TargetName = 'Target'
AverageName = 'Average'
AverageBaseName = 'AverageBase'
Leg = 0
LegCount = 8
LegName = ['1', '2', '3', '4', '5', '6', '7', '8']

activeScene =
listObject = activeScene.objects
ConMaxReached = 0
ConMidReached = 0
XYZMax = 0
while Leg < LegCount:

    if listObject != None:
        for obj in activeScene.objects:                         
            if Leg < LegCount:   
                if == True:
                    if == True:
                            MasterLegList =[:-len(SpiderLeg)-1]
                            if MasterLegList.endswith(LegName[Leg]) == True:
                                Master = obj
                    if == True:
                            TargetLegList =[:-len(SpiderLeg)-1]
                            if TargetLegList.endswith(LegName[Leg]) == True:
                                Target = obj
                    if == True:
                        if == True:
                            AverageBase = obj
                            Average = obj
                    if == True:
                        MasterLegNo =[:-len(SpiderLeg)-1]
                        if MasterLegNo.endswith(LegName[Leg]) == True:
                            XMaster,YMaster,ZMaster = Master.getLocation('worldspace')
                            XTarget,YTarget,ZTarget = Target.getLocation('worldspace')
                            XLength = XTarget - XMaster
                            YLength = YTarget - YMaster
                            ZLength = ZTarget - ZMaster
                            XYLength = math.sqrt((XLength*XLength)+(YLength*YLength))
                            XYZLength = math.sqrt((XYLength*XYLength)+(ZLength*ZLength))
                            if XYZLength > 0:
                                Target.SizeX = (((XYZLength)*100.00)/(MaxDist*5.00))+1.00
                            if XYZLength > XYZMax and ConMaxReached == 0 and Leg < LegCount/2:
                                XYZMax = XYZLength
                                if XYZLength > 0:
                                    Average.SizeX = (((XYZMax)*100.00)/(MaxDist*5.00))+1.00
                            if XYZMax > MaxDist/2 and Leg < LegCount/2:
                                ConMidReached = 1
                            if ConMidReached == 1 and Leg >= LegCount/2 and XYZLength > XYZMax:
                                Target.LocX = XMaster
                                Target.LocY = YMaster
                                Target.LocZ = ZMaster
                                Target.SizeX = 1.00    
                        ###Calcs if the legs if any are at there MaxDist
                            if XYZLength > MaxDist and ConMaxReached == 0 and Leg < LegCount/2:
                                Target.LocX = XMaster
                                Target.LocY = YMaster
                                Target.LocZ = ZMaster
                                Target.SizeX = 1.00    
                                Average.SizeX = 1.00
                                ConMaxReached = 1
                                Leg = -1
                        ###if any of the legs are at there MaxDist Reset
                            if ConMaxReached == 1 and Leg < LegCount/2:
                                Target.LocX = XMaster
                                Target.LocY = YMaster
                                Target.LocZ = ZMaster
                                Target.SizeX = 1.00    
                                Average.SizeX = 1.00
                        ###Sets the Start Pose                        
                            if frame == 1:
                                if Leg < LegCount/2:                    ###For the controle legs
                                    Target.LocX = XMaster-(MaxDist/2)
                                if Leg > LegCount/2:                    ###For the other legs
                                    Target.LocX = XMaster
                                Average.LocX = 0                        ###For the Average Empty
                                Average.LocY = 0
                                Average.LocZ = 0

    Leg = Leg+1

Umm, Sweet job with the script. but…spiders only have 2 body pieces…

I’d rather say awesome job :slight_smile: I really like how you managed to automate the legs, now you can animate an army of ants, eeh, spiders :).
Only hint would be maybe - if u do a rig, try to keep as much as possible inside the armature, it helps a lot when you duplicate the rigs.
With a good model, it could be really nice. You could e.g. use boids particles with surface constraint to make huge crowds :slight_smile:

Thanks guys! yea I know the model sucks :frowning: I thought I would just whack something on so you could tell at least which way the front was. I do intend to model something decent!

As for the Rig setup, at the moment I am using emptys, SO do you think I would be better using bones in one Armature? hmmm. I should be able to do that.

This is my first proper go at Python in Blender so I’m still a bit shaky, also can someone who know what there doing read through my script, like I said this is my first script and I’m sure there will be a better way to do things.

There is a bit where I need Empty to do something when XYZLength == 5 

XYZLength goes from 0 to 9 during the animation

but if I use an If statement it doesn't work because XYZLength only eqauls 5 on a fractional frame?

how would one do this?

I cant use > because then it would effect 5 thought to 9 aswell?

you need a second variable, kind of flag-boolean

#setup a global variable
do_it_gt5 = 0

# in the looping program check like this...
if do_it_gt5 == 0 and XYZLength > 5:
    do_it_gt5 = 1
    #do the special move
#and if you need such thing periodically, may be after XYZLength starts again from 0
if XYZLengtz == 0:
    do_it_gt5 = 0

i did not check your example-blend-file, if you use a script executet every frame (in the script-property) then you may need to setup a property-variable in the Logic-Panel to have some kind of global variable to store values.