Search code examples
3dgame-physicsphysicsgodotphysics-engine

How do I fix my jump code for a 3D platformer?


Im trying to make a 3D third person platformer in Godot and I'm following an online tutorial. I've got everything scripted the same way it is in the tutorial and my jump isnt working the same way. The player only moves a few cm off the ground and then falls really slowly back down to the ground.

extends KinematicBody

var curHp : int = 10
var maxHp : int = 10
var damage : int = 1

var gold : int = 0

var attackRate : float = 0.3
var lastAttackTime : int = 0

var moveSpeed : float = 10
var jumpForce : float = 10
var gravity : float = 15

var vel : Vector3 = Vector3()

onready var camera = get_node("CameraOrbit")
onready var attackRayCast = get_node("RayCast")


func _physics_process(delta):

    vel.x = 0
    vel.y = 0

    var input = Vector3()


if Input.is_action_pressed("move_forward"):
    input.z += 1
if Input.is_action_pressed("move_backward"):
    input.z -= 1
if Input.is_action_pressed("move_left"):
    input.x += 1
if Input.is_action_pressed("move_right"):
    input.x -= 1


input = input.normalized()


var dir = (transform.basis.z * input.z + transform.basis.x * input.x)


vel.x = dir.x * moveSpeed
vel.z = dir.z * moveSpeed


vel.y -= gravity * delta

if Input.is_action_pressed("jump") and is_on_floor():
    vel.y += jumpForce


vel = move_and_slide(vel, Vector3.UP)

Solution

  • There seems to be some unusual things going on with the indentation, so it is a little unclear (is the input logic supposed to be in the _physics_process function, or separate?), but what it looks like is that the y velocity is reset to 0 every tick. This means that whatever modifications you make with vel.y is reset to 0 every time. This means that when you jump, you move up gravity * delta units, and then y velocity is reset back to 0. After that, vel.y is set to gravity * delta and you move that much every tick before vel.y is set back to 0.

    What you probably want to do is to initialize vel.x and vel.y within the initializer instead of within the process loop function. This should ensure standards physics behavior on the y axis. To let your character stop moving on the x axis when you are not pressing a button, you can add some code to the physics loop to accelerate to a stop whenever input.x and input.z is 0.