0 votes

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

Godot version 3.2.3
in Engine by (71 points)
edited by

2 Answers

0 votes
Best answer

As of now i came up with an temp-workaround after looking through some community questions.
I found this and build upon it: https://godotengine.org/qa/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

by (71 points)
edited by
0 votes

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)))
by (1,714 points)

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".

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.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.