Trying to set up a classic 'resident evil' 3d person template with static camera switching. Player's movement should always be related to the current camera angle meaning that forward should always be where the camera is pointing at. This is the closest I could get so far but I still get diagonal movement with some camera angles.

What am I missing here? Any ideas?

    void ProcessMovement(float delta)
    {
        desiredDir = new Vector3();
        bIsMoving = false;

        if (sceneCamera == null) return;

        Vector3 rightAxis = -sceneCamera.GetGlobalTransform().basis.z;
        Vector3 forwardAxis = sceneCamera.GetGlobalTransform().basis.x;

        // Move forward
        if (Input.IsActionPressed("ui_up"))
        {
            //GD.Print("Moving forward");
            desiredDir -= forwardAxis;
            bIsMoving = true;
        }

        // Move backward
        if (Input.IsActionPressed("ui_down"))
        {
            //GD.Print("Moving backward");
            desiredDir += forwardAxis;
            bIsMoving = true;
        }

        // Move left
        if (Input.IsActionPressed("ui_left"))
        {
            //GD.Print("Moving left");
            desiredDir -= rightAxis;
            bIsMoving = true;
        }

        // Move right
        if (Input.IsActionPressed("ui_right"))
        {
            //GD.Print("Moving right");
            desiredDir += rightAxis;
            bIsMoving = true;
        }

        desiredDir.y = 0;
        desiredDir = desiredDir.Normalized();

        velocity.y = 0;
        float newAccel;

        if (desiredDir.Dot(velocity) > 0) newAccel = ACCELERATION;
        else newAccel = DEACCELERATION;

        Vector3 moveDirection = desiredDir * MOVE_SPEED;
        velocity = velocity.LinearInterpolate(moveDirection, newAccel * delta);

        Vector3 up = new Vector3(0f,1f, 0f);

        velocity = MoveAndSlide(velocity, up, 0.05f, 4, Mathf.Deg2Rad(MAX_SLOPE_ANGLE));

        // TODO: Get player to rotate towards move direction.
        Vector3 lookAtRotation = GetTransform().origin + desiredDir;
        LookAt(lookAtRotation, up);
    }

Nevermind the problem is in the C# implementation. The same code translated in GDScript works flawlessly.

Probably worths a report.

func ProcessMovement(delta):
	
	if sceneCamera == null:
		print("Failed to find a camera.")
		return
		
	var dir = Vector3()
	var inputMoveVector = Vector2()
	var aim = sceneCamera.get_global_transform().basis
	
	if Input.is_action_pressed("ui_up"):
		inputMoveVector.y +=1
	if Input.is_action_pressed("ui_down"):
		inputMoveVector.y -=1
	if Input.is_action_pressed("ui_left"):
		inputMoveVector.x -=1
	if Input.is_action_pressed("ui_right"):
		inputMoveVector.x +=1
		
	inputMoveVector = inputMoveVector.normalized()
	dir += -aim.z * inputMoveVector.y
	dir += aim.x * inputMoveVector.x
	
	dir.y = 0
	dir = dir.normalized()
	
	velocity.y = 0
	var moveDir = dir * 5
	var up = Vector3(0,1,0)
	velocity = velocity.linear_interpolate(moveDir, 16 * delta)
	velocity = move_and_slide(velocity, up, 0.05, 4, 45)
	
	var lookDir = get_global_transform().origin + moveDir
	look_at(lookDir, up)

@JohnEK said: Nevermind the problem is in the C# implementation.

Probably worths a report.

Yes, always! Especially right now, while it's still in beta and there might be more opportunity for making breaking changes if necessary.

I think the problem lies in GetGlobalTransfrom().basis that returns a different value when compared to its get_global_transform().basis brother.

5 years later