0 votes

Hi everyone! I'm learning to use Godot with the brand new GDNative (C++17) API and I hit a wall. Been hitting hit for like 4 hours...

I'm following the FPS Tutorial from here but converting GDScript code to C++, which looks mostly the same. But, when I move in any direction, it goes in a weird, unexpected direction. In a hope to know if it's my code or the engine that's bugged, I copied the code from the tutorial and replaced my class with it, and it works as expected... Why? What am I doing wrong?

I uploaded the whole project to my Dropbox, with compiled binaries for Windows 64-bit (~2mb) if it is needed.

C++ functions that process movement :

void Player::process_input()
{
    auto xform = _cam->get_global_transform();
    _dir = {};

    auto input_vector = Vector2();

    if (Input::is_action_pressed("move_forward"))
        input_vector.y += 1;
    if (Input::is_action_pressed("move_back"))
        input_vector.y -= 1;
    if (Input::is_action_pressed("move_left"))
        input_vector.x -= 1;
    if (Input::is_action_pressed("move_right"))
        input_vector.x += 1;

    input_vector.normalize();

    _dir += -xform.basis.z.normalized() * input_vector.y;
    _dir += xform.basis.x.normalized() * input_vector.x;

    if (Input::is_action_just_pressed("ui_cancel"))
        Input::set_mouse_mode(Input::get_mouse_mode() == Input::MOUSE_MODE_VISIBLE
            ? Input::MOUSE_MODE_CAPTURED
            : Input::MOUSE_MODE_VISIBLE);
}

void Player::process_movement(double delta)
{
    _dir.y = 0;
    _dir.normalize();

    _vel.y += delta * GRAVITY;

    auto hvel = _vel;
    hvel.y = 0;

    auto target = _dir;
    target *= MAX_SPEED;

    real_t accel = 0;
    if (_dir.dot(hvel) > 0)
        accel = ACCEL;
    else
        accel = DEACCEL;

    hvel = hvel.linear_interpolate(target, accel * (real_t) delta);
    _vel.x = hvel.x;
    _vel.z = hvel.z;
    _vel = owner->move_and_slide(_vel, Vector3(0, 1, 0), 0.05, 4, deg2rad(MAX_SLOPE_ANGLE));
}

The same functions in GDScript :

func process_input(delta):

    # ----------------------------------
    # Walking
    dir = Vector3()
    var cam_xform = camera.get_global_transform()

    var input_movement_vector = Vector2()

    if Input.is_action_pressed("move_forward"):
        input_movement_vector.y += 1
    if Input.is_action_pressed("move_back"):
        input_movement_vector.y -= 1
    if Input.is_action_pressed("move_left"):
        input_movement_vector.x -= 1
    if Input.is_action_pressed("move_right"):
        input_movement_vector.x += 1

    input_movement_vector = input_movement_vector.normalized()

    dir += -cam_xform.basis.z.normalized() * input_movement_vector.y
    dir += cam_xform.basis.x.normalized() * input_movement_vector.x
    # ----------------------------------

    # ----------------------------------
    # Capturing/Freeing the cursor
    if Input.is_action_just_pressed("ui_cancel"):
        if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
            Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
        else:
            Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
    # ----------------------------------

func process_movement(delta):
    dir.y = 0
    dir = dir.normalized()

    vel.y += delta * GRAVITY

    var hvel = vel
    hvel.y = 0

    var target = dir
    target *= MAX_SPEED

    var accel
    if dir.dot(hvel) > 0:
        accel = ACCEL
    else:
        accel = DEACCEL

    hvel = hvel.linear_interpolate(target, accel*delta)
    vel.x = hvel.x
    vel.z = hvel.z
    vel = move_and_slide(vel, Vector3(0, 1, 0), 0.05, 4, deg2rad(MAX_SLOPE_ANGLE))
asked Jun 16, 2018 in Engine by Daniel Grondin (19 points)

1 Answer

0 votes
Best answer

Asked the question on the Discord and found the problem : Basis' axis are transposed in GDNative, I needed to use basis.get_axis(0) instead of basis.x and the same for the other axis. This isn't documented anywhere though...

Thanks to the Discord guys for helping!

answered Jun 17, 2018 by Daniel Grondin (19 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.