# How to access character (physics type) via python to update it's jump force in real time?

I would like to know if it's possible to access the jump speed via python to set different values for it. (.game.jump_speed / GameObjectSettings.jump_speed).

Is there a python script sample somewhere?

Here is a practical example to illustrate this question:

Let's say you have two types of platforms: Red and Blue. When one collides with the red platform this event triggers a jump force of 10.00 (ten). When one collides with the blue platform this event triggers a jump force of 20.00 (twenty).

There is a .blend for prototyping here (google drive, saved in Blender version 2.78c): https://drive.google.com/file/d/0Byr4NYScNOlRMkkwWGx5VG5ETEk/view?usp=sharing (Controls: WASD to move the character).

Physics pannel:

Current api (2.78c) GameObjectSettings.jump_speed

GameObjectSettings is part of bpy which only work inside of blender and only in Blender, this means that your game using bpy and bge only will work inside Blender because bpy will not work in standalone and you dont want that if you are making a game but if you are makin sortsof simulation and you will be using always blender then you can use bge and bpy.

You can access jump_speed:

from bpy import data

data.objects["Cube"].game.jump_speed = 50
print(data.objects["Cube"].game.jump_speed)


As soon as you run the script 50 will be the value for jump force in physics property panel:

here you can found some (old) good bge python tutorials

If you want in game dinamically change the jump speed you can use the next script portion was extracted from one of the tutorials, thanks to Goran Milovanovic

script

from bge import logic
from mathutils import Vector
import math

"""
Goran's 2.6x FPS base-frame

2011 - Goran Milovanvic - nilunder.com

"""
def __init__(self, cont, own):
self.cont = cont
self.body = own
self.sen_key_w = self.cont.sensors["W"]
self.sen_key_s = self.cont.sensors["S"]
self.sen_key_a = self.cont.sensors["A"]
self.sen_key_d = self.cont.sensors["D"]
self.sen_key_space = self.cont.sensors["space"]
self.sen_col_onground = self.cont.sensors["onground"]
self.speed_ground = 4
self.speed_jump = self.speed_ground * 0.8
self.main = self._inAir

def _getMoveVec(self):
forward_back = self.sen_key_w.positive - self.sen_key_s.positive
left_right = self.sen_key_d.positive - self.sen_key_a.positive
velocity = Vector((left_right, forward_back, 0))
return velocity

def _onGround(self):
vec_velocity = self._getMoveVec()
vec_velocity.magnitude = self.speed_ground
if self.sen_key_space.positive:
vec_velocity.z = self.speed_jump
self.body.setLinearVelocity(vec_velocity, 1)
if not self.sen_col_onground.positive:
self.main = self._inAir

def _inAir(self):
if self.sen_col_onground.positive:
self.main = self._onGround

"""Strapicarus 2017"""
class Player:
def __init__(self, cont, body):
self.body = body
self.main = self.walking

def walking(self):
self.change_speed(1)

def change_speed(self, speed):
else:
return

def main(cont):
if not 'init' in cont.owner.getPropertyNames():
cont.owner['player'] = Player(cont, cont.owner)
cont.owner['init'] = True
cont.owner['player'].main()

main(logic.getCurrentController())


LogicBricks

Physics panel

Well a just download your blend and you put the right blend this time (i forgot to mention that before answer), and i test ¿if i change the loc z in motion actuator the character will jump higher? and YES it works.

So you just need increase the loc z value to set the jump speed for that motion actuator:

And if you want a python way here is to:

jump.py

from bge import logic

def main(cont):
jumpact = cont.actuators['jumpSpeed']
colsen = cont.sensors['Blue']
if not 'init' in cont.owner.getPropertyNames():
cont.owner['init'] = True
cont.owner['_onair'] = False
cont.owner['jumpSpeed'] = 0.0
print('init...')
return

if not cont.owner['_onair'] and colsen.positive:
if  cont.owner['jumpSpeed'] < 10.0:
cont.owner['jumpSpeed'] += 1
jumpact.dLoc = (0,0,cont.owner['jumpSpeed'])
print(jumpact.dLoc.z)
else:
cont.owner['jumpSpeed'] = 0.0
cont.activate(jumpact)
cont.owner['_onair'] = True
return
else:
cont.deactivate(jumpact)
cont.owner['_onair'] = False
return
#    print(dir(jumpact))
#    print(jumpact.force)
#    print(jumpact.linV)
#    print(jumpact.torque)
#    print(jumpact.dLoc) #FOUND IT ! xD

main(logic.getCurrentController())


Logic editor

Blend file

• Dear Strapicarus, Thank you very much for your reply. But in my case I need a solution that works inside the Blender Game Engine (real time update) and with the "charachter" physics type. I also don't need other movements other than jump. The bounty prize is yours because of the effort. But I still consider this question without solution ;) Greetings! Ortiz – chicOrtiz Jul 3 '17 at 17:39
• I think i found a solution check it in the edit. – Strapicarus Jul 3 '17 at 20:22
• Hi Strapicarus! I tested your file in Blender 2.78c, but the jump is behaving like I'm using a simple motion value applied to a dynamic actor. The jump is not behaving like the charachter physics yet. Thank you! – chicOrtiz Jul 4 '17 at 15:29

I believe what you are asking for is not possible in Blender 2.78b. We will need to recreate the jump functionality.

The jump pads will require a float property called ['jumpSpeed'] and collision enabled in its physics tab. Static physics type should work.

The rest is explained below.

#if we put the python controler in modual mode,
#then it can pass the currentController as the first argument
def input(cont):
#if you have problems with floating after a jump, then increse Max Fall Speed
own = cont.owner

#if were going to use the Characture Wrapper, then we need to get it first
import bge
pysOwn = bge.constraints.getCharacter(own)

#this is how i handle keybinds
clicked = bge.logic.keyboard.active_events
click = {bge.logic.KX_INPUT_JUST_ACTIVATED, bge.logic.KX_INPUT_ACTIVE}

#if the KEY is not in active_events then dict.get() will return None
forward = clicked.get(bge.events.WKEY)
backward = clicked.get(bge.events.SKEY)
leftward = clicked.get(bge.events.AKEY)
rightward = clicked.get(bge.events.DKEY)
spaceward = clicked.get(bge.events.SPACEKEY)

#if the jump count is less then the max jumps then we can jump
if spaceward == bge.logic.KX_INPUT_JUST_ACTIVATED and own['jumpCount'] < pysOwn.maxJumps:
#we can get a sensor even if its not connected to the current controller
#it may have to be connected to at least one controller
#if the collision sensor hits at least one object with the jumpSpeed property then we get it,
#otherwise this get None
hitObj = own.sensors['Collision'].hitObject
#if theres a hitObj, then we use the jumpSpeed provided by that object,
#otherwise we use the default on the char
if hitObj:
jumpSpeed = hitObj['jumpSpeed']
else:
jumpSpeed = own['jumpSpeed']

#we move the char along the z axis by the jumpSpeed
x = pysOwn.walkDirection.x
y = pysOwn.walkDirection.y
z = pysOwn.walkDirection.z + jumpSpeed
pysOwn.walkDirection = (x,y,z)

#this will trigger the property sensor, so we know when to stop jumping
own['jumping'] = True
#this sets the number of times we've jumped scence landind
own['jumpCount'] += 1

#if the char is on the ground or has the walkAir ablity then it can move, otherwise it can't
if pysOwn.onGround or own['walkAir']:

#we'r going to replace the current walkDirection with a new one
x = 0
y = 0
z = pysOwn.walkDirection.z

speed = own['walkSpeed']

if forward in click:
y += speed
if backward in click:
y -= speed
if leftward in click:
x -= speed
if rightward in click:
x += speed

#this converts our local vector into a world vector
from mathutils import Vector
vec = Vector((x,y,z))
vec = own.worldOrientation * vec

#apply the walkDirection
pysOwn.walkDirection = vec

def stopJump(cont):
#this function asumes it will only be run if own['jumping'] == True
own = cont.owner
import bge
pysOwn = bge.constraints.getCharacter(own)

#if the char is on the ground, stop jumping and reset
if pysOwn.onGround:
pysOwn.walkDirection = (0,0,0)
own['jumping'] = False
own['jumpCount'] = 0


• Hello Otto! Thank you for your time. I tried to apply your jump setup withouth sucess. I hosted my attempt here [link]drive.google.com/file/d/0Byr4NYScNOlRWFdibHJPTWZ6R2c/… I don't know how I should trigger the jump. I confess that your python script is too advanced for me :) – chicOrtiz Jul 4 '17 at 15:34
from bge import constraints

cont = logic.getCurrentController()
owner = cont.owner

character = constraints.getCharacter(owner)

# When colliding use:
character.gravity = value float

# Set a different value for each platform you want to change the height of the jump