Character Control

We will make character physics controller which is KX_CharacterWrapper type. This allows us to check if the character has landed, control number of jumps it can do, etc.

Setup

Select the cube, change it's physics type to Character, drag it up on the Z axis to around 3-4.

Logic Bricks

To setup the logic bricks, we need to know how the player will be controller. My guess is something like this.

logic bricks setup
Logic Bricks Setup

The keyboard keys will be controlled with python.

Coding

Import the game engine module, define our python controller and owner.

try:
    import Range
except:
    import bge as Range

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

def move():
    pass

The move function will run in a loop. Next we need to move our character when the keyboard sensors is triggered.

def move():
    keyboard = cont.sensors["Keyboard"] # Get sensor as "keyboard"
    y = 0 # Forward / Backward
    z = 0 # Turn
    jump = (0,0,0) # Jump Direction
    if keyboard.positive: # If keyboard is triggered
        if 45 in keyboard.inputs: # W key
            y = 1/8
        if 23 in keyboard.inputs: # A key
            z = 1/8
        if 41 in keyboard.inputs: # S key
            y = -1/8
        if 26 in keyboard.inputs: # D key
            z = -1/8
        if 8 in keyboard.inputs:  # SPACE key
            pass # Do nothing, will be implemented later
        else: # Reset everything
        	x = 0
        	z = 0
        	jump = 0

Here, we've setup the movement when the keyboard is pressed. Now we need to get the character ID.

Getting the character ID is mandatory or the character you control becomes KX_GameObject.

player = Range.constraints.getCharacter(own)

We got our character ID, now we need to implement the player movement.

def move():
    keyboard = cont.sensors["Keyboard"]
    y = 0
    z = 0
    jump = (0,0,0)
    if keyboard.positive:
        if 45 in keyboard.inputs:
            y = 1/8
        if 23 in keyboard.inputs:
            z = 1/8
        if 41 in keyboard.inputs:
            y = -1/8
        if 26 in keyboard.inputs:
            z = -1/8
        if 8 in keyboard.inputs:
            player.jump() # The proper jump
    else:
        x = 0
        z = 0
        jump = 0
                    
    player.walkDirection = (0,y,0) # Movement but in world coordinates
    own.applyRotation((0,0,z), True) # Turn left and right

If you run the script, the character moves in world coordinates, to solve this we multiply worldOrientation that returns us Matrix with the tuple (0,y,0) which will be converted into a Vector with mathutils module.

player.walkDirection = own.worldOrientation * Vector((0,y,0))

And we create a property that returns us the KX_CharacterWrapper.onGround as True or False.

own["landed"] = player.onGround

And the final code looks like this.

try:
    import Range
except:
    import bge as Range

from mathutils import Vector
    
cont = Range.logic.getCurrentController()
own = cont.owner
player = Range.constraints.getCharacter(own)

def move():
    keyboard = cont.sensors["Keyboard"]
    y = 0
    z = 0
    jump = (0,0,0)
    if keyboard.positive:
        if 45 in keyboard.inputs:
            y = 1/8
        if 23 in keyboard.inputs:
            z = 1/8
        if 41 in keyboard.inputs:
            y = -1/8
        if 26 in keyboard.inputs:
            z = -1/8
        if 8 in keyboard.inputs:
            player.jump()
    else:
        x = 0
        z = 0
        jump = 0
                    
    player.walkDirection = own.worldOrientation * Vector((0,y,0))
    own.applyRotation((0,0,z), True)
    own["landed"] = player.onGround

Download the project file.