Hi guys,

I'm attempting to port over what I have in Unity3D to Godot 3.0, and so far it's been fairly simple, but I am stuck on some basic movement code and I can't quite find the commands to work it out.

Basically, I want it so that my character responds to both the joystick input and as well as keyboard and mouse input. I think the solution is I'm just going to have to check to see if the user has a joystick plugged in at startup, if they do I'll use it, otherwise default to mouse+keyboard, but it would be nice if someone could tell me how to sett up an input axis that uses both control schemes!

The other thing is that I want my player to rotate depending on input provided, so if you start to move down the character will rotate and face down. Same with all other directions. So far, the only directions that work are left/right, and I'm not sure why that would be the case.

I have a video showing what I mean about rotation and positioning:

And here is my code as it is currently: extends KinematicBody


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

var thisGravity = 0
var velocity = Vector3()

var direction = Vector3(0, 0, 0)

func _ready():
	set_physics_process(true)

func _physics_process(delta):
	_apply_gravity(delta)
	_jump()
	_move_player()
	
func _move_player():
	# store joystick input
	var input_axis = Vector2(Input.get_joy_axis(0, JOY_AXIS_0), Input.get_joy_axis(0, JOY_AXIS_1))
	
	var h = input_axis.x
	var v = input_axis.y
	
	# set the player's rotation to the values as given by the joystick
	set_rotation(Vector3(0, input_axis.angle(), 0))
	
	direction = Vector3(h, 0, v)
	
	# var forward = Vector3()
	
	# add the input values to the velocity
	velocity.x = h * MoveSpeed
	velocity.y = thisGravity
	velocity.z = v * MoveSpeed
	
	# move the player
	velocity = move_and_slide(velocity, Vector3(0, 1, 0))
	
func _apply_gravity(delta):
	if is_on_floor():
		thisGravity = 0
	else:
		thisGravity += Gravity * GravityMultiplier * delta

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

And lastly, relating to the above paragraph, how would one determine an object's Forward Vector in GD script?

For all of this, I would like to use the KinematicBody for my character as it seems by far the easiest method to work things out. However, if someone has another suggestion or knows of a way to get what I want done with rigidbodies, don't be afraid to tell me to change haha!

Thanks guys, I'm loving Godot 3.0 so far.

While I have no answers for the input stuff, I think I can help with the other problems:

After watching the video I think you have everything correct as far as turning the input axis into rotation. I think the solution is just simply multiplying input_axis.y by negative one. In the video it looks like what's happening is when your moving forwards or backwards, the forward arrow is pointing in the opposite direction relative to the y axis, so flipping it should work.


You can get a spatial's relative forward vector by using the basis. Here's the code:

"The Z axis relative to the object's local transform (generally is considered forward vector)" spatial.transform.basis.z.normalized() "Same as above, but relative to world space as opposed to local space" spatial.global_transform.basis.z.normalized() # "The X axis relative to the object's local transform (generally is considered the left vector)" spatial.transform.basis.x.normalized() "Same as above, but relative to world space as opposed to local space." spatial.global_transform.basis.x.normalized() # "The Y axis relative to the object's local transform (generally is considered upwards vector)" spatial.transform.basis.y.normalized() "Same as above, but relative to world space as opposed to local space." spatial.global_transform.basis.y.normalized()

I know you didn't ask for all of the relative vectors, but I thought I'd post them all in case you need them (and for reference for others). If you multiply any of them by negative one you get the opposite (so the forward vector becomes the backwards vector).

I learned all of this from this article (though it's for Godot 2)

@TwistedTwigleg Hey, thanks so much! I don't mind reading more information, I'll take any and all I can get on how to do this stuff in GDScript! And thanks for that link!

Hehe, I first flipped input_axis.y without realizing it would also affect my movement, so my solution to that was this...

    	# set the player's rotation to the values as given by the joystick
    	# first flip input_axis.y
    	var rotation_axis = Vector2(input_axis.x, input_axis.y * -1)
    	set_rotation(Vector3(0, rotation_axis.angle(), 0))

This also gives me the benefit of debugging that particular variable in the future.

Thanks!

5 years later