Random character jumping animation

How can I make a character do random jump animation??

For example, there are 3 sets of different looking jump animations, and when the player presses space there will be a random jump animation everytime

http://docs.python.org/2/library/random.html#random.randrange ?

In player
property X
trigger

Keypress Jump ------------------and ---------------------------------------trigger = 1
if X = 0 ----------------------/

if trigger = 1 ---------------------Python
___________-------------------and---------------------------------------trigger = 0

property sensor X =min 1 max 3---------------------------and----------------------animation Jump1
___________________________________________----------------------motion jump
____________________________________________---------------------X=0

property sensor X =min 4 max 7---------------------------and----------------------animation Jump1
___________________________________________----------------------motion jump
____________________________________________---------------------X=0
property sensor X =min 8 max 11---------------------------and----------------------animation Jump1
___________________________________________----------------------motion jump
____________________________________________---------------------X=0

in python
own[‘X’] = random.randrange(1, 11[, 1])

I am not sure about the python as I grabbed it and have not ran it yet :slight_smile:

Using python, you can use the random.choice function to select a random action from a list of actions:


import random

random_action = random.choice(['action_1','action_2', 'action_3', 'action_4'])

Then you can play the action by passing the string like gameobject.playAction(random_action, 0, 10). This doesn’t take into account the start/end of the actions, but you could do that by using dictionaries or even separate classes to handle the actions. Figuring out the best method depends on how far you want to go with this.

with a logic for loop you can trigger the action and control the animation length

Property sensor interval Min =1 max =(animation length -1)-------and------------Add 1 to"Sequence"

if (start animation condition) -----------------and----------------------“Sequence =1”
(when “Sequence” = 1) ------------and-----------------------------------trigger action
if “Sequence” = animation length-----------------------------------------and-----------Sequence = 0

this is nice because you can have the sequence apply forces as well :slight_smile:
you can make many of these and use another property to decide which loop to use,

(when “Sequence” = 1) ------------and-----------------------------------trigger action
if “Sequence” = animation length-----------------------------------------and-----------Sequence = 0

it’s probably easiest to set the animation length using a small python script, but you could also use logic states for each animation, however actions can not be mixed as far as I know…

I am working with using the sequencer to animate using force, SetLoc, torque etc

in each “ik target”
always---------------------------------and----------------Copy property Sequence from “Player”
if Sequence (range) ----------------and----------------apply(motion)

this allows for overlapping “force maps” which can conflict, (like you blocking my punch)

but I am a newb in pythonisse…

i’ve written an animation handler recently, this is what it looks like. its most likely not perfect but does the job. can be run on several characters at the same time, the relevant variables are stored as game properties.


import bge
from bge import logic, events, render
import time
import math


class animations:
    
    def __init__(self, cont):
        self.cont = logic.getCurrentController()
        scene = logic.getCurrentScene()
        
        #character collision object, holds properties
        self.pawn = self.cont.owner
        #character armature
        self.rig = scene.objects[self.pawn['rig']]
        #character name
        self.name = self.pawn['charname']


    def callAnim(self, anim, speed):
        #handles the main character animations. animations run on layer 0
        #main calls this whenever animation changes or finishes
        
        #frame data for the animations. this data is used to play the actions at the correct frames
        #careful with the brackets there are lists in the list
        #variations, startframe, endframe, switch chance, min plays, max plays
        frameData = {
            'idle' : [3, [0, 200, 400], [120, 320, 800], [60, 60, 100], [5, 5, 1], [10, 10, 1]],        
            'run' : [1, [0], [39], [0], [1], [1]],
            'walk' : [1, [0], [59], [0], [1], [1]],
        }
        #animation data, this could be included in frameData if desired
        #animation name, interrupt (can be used to lock the pawn), transition (a specific follow up animation), blend (frames to blend)
        animData = {
            'idle' : ['idle', True, 'any', 20,],
            'run' : ['run', True, 'any', 10],
            'walk' : ['walk', True, 'any', 10],
        }


        #check if the requested animation exists
        if anim in animData:
            #choose a random variation if there are any available
            if frameData[anim][0] > 1:
                #check for the minimum and maximum amount of plays required
                if (self.pawn['animPlays'] >= frameData[anim][3][self.pawn['animVar']] or
                self.pawn['animPlays'] >= frameData[anim][4][self.pawn['animVar']]):
                    #roll if the animation is changed
                    if (bge.logic.getRandomFloat()*100) < frameData[anim][2][self.pawn['animVar']]:
                        #roll for a new animation and reset the play counter
                        self.pawn['animVar'] = int(bge.logic.getRandomFloat()*frameData[anim][0])
                        self.pawn['animPlays'] = 0
                #set the frame data for playback
                startFrame = (frameData[anim][1][self.pawn['animVar']])
                endFrame = (frameData[anim][2][self.pawn['animVar']])
                self.pawn['animPlays'] += 1
            else:
                #no variations: just get the data
                self.pawn['animVar'] = 0
                startFrame = frameData[anim][1][0]
                endFrame = frameData[anim][2][0]
            #set relevant pawn properties
            self.pawn['interrupt'] = animData[anim][1]
            self.pawn['transition'] = animData[anim][2]
            self.pawn['frames'] = endFrame
            self.pawn['animation'] = anim
            #play the animation
            self.rig.playAction(self.name + ' ' + animData[anim][0], startFrame, endFrame, layer=0, layer_weight=0,  blendin=animData[anim][3], play_mode=bge.logic.KX_ACTION_MODE_PLAY, speed = speed)
        else:
            #error message if animation is not in data
            print('error: animation "' + anim + '" not available')
    
    def main(self):
        #get the current frame
        self.pawn['currentFrame'] = self.rig.getActionFrame(0)
        
        #switches animation to a specific other animation after finished playing
        #transitions are stored in callAnim, animData
        if (self.pawn['transition'] != 'any' and 
        self.pawn['currentFrame'] >= self.pawn['frames']):
            if self.pawn['animation'] != self.pawn['transition']:
                self.callAnim(self.pawn['transition'], 1)
        #switches animation to the current action
        elif self.pawn['animation'] != self.pawn['action']:
            self.callAnim(self.pawn['action'], 1)
        #handles looping of the current animation
        elif self.pawn['currentFrame'] >= self.pawn['frames']:
            self.callAnim(self.pawn['action'], 1)


def main():
    animations_ = animations(logic.getCurrentController())
    animations_.main()


#the script runs in module mode every frame on the character pawn (collision/physics object)
#the following properties are needed:
#currentFrame   - integer   - current animation frame number, layer 0
#action         - string    - current action the character performs. This is set in a control script e.g. for player input or AI
#animation      - string    - current animation playing
#frames         - integer   - frame number the current animation ends at
#transition     - string    - the follow up animation after the current one ends
#rig            - string    - the armature object's name
#charname       - string    - prefix to this character's actions
#animVar        - integer   - currently running animation variation
#animPlays      - integer   - counter for the current animation variation
#interrupt      - boolean   - can be used in control script to lock the pawn