Help on Normalizing movement

Godot Version

godot 4


(note the program was originaly designed for a much wider text box so it looks cramped like this)
func _physics_process(delta): # handles movement on the x and z axis relative to the player (Unsure if the movement is normalized) var direction = Input.get_vector("move_forward", "move_backward", "move_left", "move_right").normalized() var input_direction_y = Input.get_axis("move_down", "move_up") velocity.x = movement_speed * (sin(rotation.y) * (direction.x) + cos(-rotation.y) * (direction.y)) velocity.z = movement_speed * (cos(rotation.y) * (direction.x) + sin(-rotation.y) * (direction.y))

This program is designed for movement using the WASD keys (linked to the “move_” input mapping) which seems to work perfectly fine except that the movement does not seem to be normalized when i test it in the editor.
My main 2 questions are

  1. how can i normalize the movement in this script?
  2. how can i check if the movement is normalized?

I have a normalized(). in there however I am not sure if it is working, as i said at the start it doesn’t seem to be.
The script is attached to a characterbody 3d node and is put inside a scene with static bodies, gravity has been removed from the script so the character floats when moving around.

One thing to point out, if these actions are keyboard input that each button should have a strength of 1.0 by default and that function get_vector and get_axis will in consequence be normalized. Except If you use a joystick it may not be normalized because of the strength value is absolute to the analog input.

Calling normalized is the best way.

Vector classes will have a function is_normalized() returning a bool. ( I’m not sure what it will do if the vector is zeros, in the case the user isn’t pressing anything)

One last note: I was never able to understand sin/cos manipulations very well, and I avoid them at all costs. Leverage vector maths and built in functions.

I assume you want to translate the input vector to the direction of the player is facing. To do this is simple with the transform3d inside of every node3d.

I would use the global transform like this

var player_input_direction = global_transform.basis * direction 

This will use the basis to rotate the input direction into player space. The only caveat to be careful with is if the player is tilted up or down so will the direction. It gets a little tedious to mitigate that. I have done it but can’t remember my code ATM.

But this is only a suggestion

1 Like

Maybe I didn’t find an elegant way…

func set_player_input():
	var move_direction_3d:Vector3 = camera_basis * v2_to_v3(self.move_direction)
	move_direction_3d.y = 0.0
	input_updated.emit(self.input, move_direction_3d.normalized(), self.aim_pos)

After I rotate the input into the camera perspective I smash the y axis and re normalize the input. So it should be full strength on the unit circle in the x and z plane.

Ah maybe another thing I missed, get vector is vector2 so I made a special function to translate that.

Vector3(vec2.x, 0.0, vec2.y)
1 Like

If you want a more detailed explanation of basis math the concept is called a “linear transformation”

1 Like

Oh ok thanks,
Note: My full program involves rotating the player up and down quite a lot,

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.