MouseMotionInput : Get axis movement like in Unity which ranges from 1.0 to -1.0 (e.g. weapon sway)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Stupido

Heyho
currently i am working on using the AnimationTree > BlendSpace2D to e.g. to “simulate” weapon-sway, when the mouse moves.

Therefore i want to apply Mouse-Movement-Input each frame which ranges from 1.0 to -1.0. Everytime the mouse is not moved the Input will be 0.0 on X and Y axis.

Unity has the Input.GetAxis(“Horizontal”) for example that gives the X value 1 to -1
Is there a way to accomplish that in Godot?

Thanks

PS.: I know that InputEventJoystickMotion has axis_position which ranges from 1 to -1

:bust_in_silhouette: Reply From: estebanmolca

This is the way I know:

func _input (event):
        if event is InputEventMouseMotion:
        print (event.relative.x)

With relative.x you get the position that the mouse had in the previous frame in x. negative if the mouse moves to the left and positive if it moves to the right. Zero if the mouse does not move. You could use that value directly to modify how much movement you want or set it between -1 and 1.
I was able to limit this value using clamp:

func _input(event):
	if event is InputEventMouseMotion:
		print(clamp(event.relative.x ,-1,1))

but it won’t give you intermediate values, if you want to get the mouse speed there is a property for that or you can use something like this:

func _input(event):
	if event is InputEventMouseMotion:
		print(lerp(0,1,clamp(event.relative.x * get_process_delta_time(),-1,1)))

Thanks for the quick replie.
Saddly this does not fit for what i was thinking to do but it gave me an idea on how i could approach it. I will write it down as an “answer”.

Stupido | 2021-03-20 15:41

:bust_in_silhouette: Reply From: Stupido

As of now i came up with an temp-workaround after looking through some community questions.
I found this and build upon it: https://forum.godotengine.org/68649/how-to-make-the-sway-effect-on-weapons-of-fps-3d-games

var mouse_moved = false 

var max_rotation  = 25
var interpolation_time = 4

var interpolation_vector_default : Vector2 = Vector2(0, 0)
var last_mouse_move_relative : Vector2
var interpolate_torwards_vector : Vector2
var current_interpolating_vector : Vector2

func _input(event):
	if event is InputEventMouseMotion:
		mouse_moved = true
		last_mouse_move_relative = Vector2(clamp(event.relative.y, -max_rotation, max_rotation), 
		clamp(event.relative.x, -max_rotation, max_rotation)) * -1
		

func _process(delta):

	if mouse_moved:
		mouse_moved = false
		interpolate_torwards_vector = last_mouse_move_relative
	else:
		interpolate_torwards_vector = interpolation_vector_default

	current_interpolating_vector = current_interpolating_vector.linear_interpolate(interpolate_torwards_vector, 
	interpolation_time * delta)
	rotation_degrees.x = current_interpolating_vector.x
	rotation_degrees.y = current_interpolating_vector.y

Everytime the mouse moved ill keep that in mind and change the vector to which i should interpolate. If on the the next frame the mouse is still moving, keep on interpolating torwads the current mouse vector otherwise return to the default vector (0, 0).

It sure can get jittery if the interpolation_time is higher than 0.02 without multiplying it with delta. If there is other ways to prevent it, great!

Edit: Fix for jittery by “*delta” in _process