[3D]Movement issues with KinematicBody character

BinaryOrangeBinaryOrange Posts: 234Member

Hey everyone,

I'm having some strange behavior occur with my KinematicBody character. First, when I first press one of the arrow keys, my character will begin to move, but when I release the keys my character will just keep going, and even when it hits a wall it will just continue to slide indefinitely.

Secondly, it's like my input isn't being listened to, and it takes several seconds for my player character to turn around and it does so in a strange sweeping motion. I thought it was my rotation code, but when I commented it out, the effect remained, my player took several seconds to respond to the opposite input.

Also, I've noted that in the Godot docs it says that "forward" is in the negative Z axis, yet when I designed my player, I had to put its nose and arms (my indicators of which way it was actually facing) on the positive X side. Maybe it's where I placed my camera? Not sure.

Here's a video showing the issues:

And here's my code:

extends KinematicBody

# inspector accessible variables
export var Gravity = -20
export var GravityMultiplier = 1
export var MoveSpeed = 20
export var TurnSpeed = 20
export var JumpHeight = 10
export var FlightHeight = 10
export var FlightSpeed = 10
export var CanDoubleJump = false

# private variables
var thisGravity = 0
var direction = Vector3()
var velocity = Vector3()

# our input floats
var h
var v

# on startup
func _ready():

# Updates the game, mostly physics stuff
func _physics_process(delta):

# moves the player
func _move_player():

    # set the player's rotation to the values as given by the joystick
    # first flip vertical axis, possible bug with rotations
    var rotation_axis = Vector2(direction.x, direction.z * -1)
    set_rotation(Vector3(0, rotation_axis.angle(), 0))

    direction = direction.normalized()
    direction = direction * MoveSpeed

    # add the input and gravity values to the velocity Vector
    velocity = Vector3(direction.x, thisGravity, direction.z)

    # move the player
    velocity = move_and_slide(velocity, Vector3(0, 1, 0))

# get and store input in our h and v variables
func _get_input(delta):
#   h = Input.get_joy_axis(0, JOY_AXIS_0)
#   v = Input.get_joy_axis(0, JOY_AXIS_1)
    if Input.is_action_pressed("ui_left"):
        direction.x -= 1
    if Input.is_action_pressed("ui_right"):
        direction.x += 1
    if Input.is_action_pressed("ui_up"):
        direction.z -= 1
    if Input.is_action_pressed("ui_down"):
        direction.z += 1

# apply gravity, pass in delta value from main physics process
func _apply_gravity(delta):
    if is_on_floor():
        thisGravity = 0
        thisGravity += Gravity * GravityMultiplier * delta

# jump our player
func _jump():
    if is_on_floor() and Input.is_action_pressed("ui_select"):
        thisGravity += JumpHeight

If anyone can offer my any insight, I'd sure appreciate it! Thanks!


Tags :


  • TwistedTwiglegTwistedTwigleg Posts: 858Admin
    Answer ✓

    Here's what I think will fix the problems:

    For the first problem, the player still moving even when the keys are not being pressed, you need to reset direction in your _get_input_function. That should fix the movement stuff because then it will not retain the input from the previous call.

    For the second problem, I'm not 100% sure, but I think it is related to the first problem. It may also be the normalization that is causing the issue. I'd try removing the normalization at line 41 and see if that fixes it.

    On the forward axis, I'm not sure. You could try rotating your player by an additional 90 degrees on the Y-axis either in code or in the scene and see if that aligns your character's forward with negative Z. You'd just need to change line 39 to set_rotation(Vector3(0, rotation_axis.angle() + deg2rad(90), 0)) and that should make it face the negative Z axis (or the positive Z axis, in which case you need to remove 90 degrees).

  • BinaryOrangeBinaryOrange Posts: 234Member
    edited February 11

    Resetting my direction vector now makes rotation not work. I'm going to dig around the Platformer 3D demo some and see if I can't figure out how they handle rotations in there. It did solve my issue of input being delayed, though, so that's a step in the right direction!

    I think I may just try to port this idea over to 2D. I've always wanted to make a 2D sidescroller, so I'll just use my idea for this game as the boiler plate. I think it will play better that way, too!

Sign In or Register to comment.