Hi, I create an isometric game with movement into 8 directions.
The movement and animation itself already works fine, issue is: when you walk diagonal and release the keys, you often end up looking horizontal/vertical. Its because you often don’t release both keys at the exact same time, there is a little difference in timing. So its suddenly switching direction.
Is there a way that even if you released both keys with a little time difference, that it still counts as if the diagonal direction was the last one, instead of switching to horizontal/vertical movement just because of a few miliseconds? Like the time span for a double click with the mouse.
While walking its no issue. I just need it for the “vLastDirection” variable, so that the proper idle animation is played when nothing is pressed, depending on the last direction you walked. A time span between both keys released of 0.1 - 0.2 seconds would be probably enough. But I have no idea on how to code it ^^’
One thing you might consider is setting up internal variables var fTimeSpentGoingInCurrentDirection:float = 0.0, var vDirectionFromLastFrame:int = -1, and var vLastDirectionLockedIn:int = -1
If the code you provided is in _process(delta), then you can do something like
Then, whenever you detect no user input for the move direction, use the vLastDirectionLockedIn.
Although, I would have to ask whether 8 directions is what you really want. If instead you allowed for arbitrary directions, then you could just make it so the direction the player faces moves gradually based on user input, and this effect would be automatic.
Interesting one
I tried something that seems to work: instead of using a timer of complex stuff that would make the code a pain in the ass to read, I tried storing a rotation under the hood that smoothly follows the direction. The movement direction is still changing rapidly, but I’m updating a vector that does not snap to the current direction but tries to snap to it over a few seconds. And that vector is the one I’m using to update the player visual.
Here’s what it looks like:
var smoothed_direction: Vector2
func _process(delta: float) -> void:
var direction = Input.get_vector("left", "right", "up", "down") # Input direction.
global_position += direction * delta * 100 # Actual movement, not affected by any smoothing.
if direction.length_squared() > 0:
# Follow the current direction with a delay.
smoothed_direction = lerp(smoothed_direction, direction, delta * 10.0)
# Compute the rotation in radians for the smoothed vector.
var rotation: float = -smoothed_direction.angle_to(Vector2.RIGHT)
# Snap the rotation to diagonals only (45°).
rotation = deg_to_rad(round(rad_to_deg(rotation) / 45.0) * 45)
# Apply the snapped rotation.
global_rotation = rotation
else:
# Reset smoothing when there's no movement to avoid issues when moving again.
smoothed_direction = direction
The remaining issue is that the rotation will be updated with a delay even when moving normally, not only when releasing the keys, so that’s definitely something my code is missing.
But while my demo code is incomplete, I believe this kind of solution is making the code more simple than a big if/else statement that would become hard to read and maintain
A quick gif of my test implementation to show that I can easily release my inputs while moving diagonally and it works like a charm.
I agree on this one, although it would only work with analog sticks. The problem would still remain when using keyboard arrows or WASD, if the input reaction is very sharp.
Yeah, my game is nearly completely hand drawn, cuz I want to give it that 90s anime look.
So I use 3D-Modelling only for characters and the area maps, export them as 2d images and then paint over them
Okay, it seems I lack too much experience to properly implement your code
And I should have probably added more information about my project. Because when used raw it works perfectly as you have shown in your gif, but for an isometric character like mine it just makes her spin xD
Then I tried it with an adaption of Ryan_Flynns idea, that worked but created a little “glitch”, when the direction changed from diagonal to vertical/horizontal while releasing the keys and then instantly snapped back into diagonal direction.
In the end the best workaround for me was to just add a little timer to the check if the animation needs to be changed in general of 0.1 seconds (I realized that 0.2 was a bit long) so it updates the animation only every 0.1 seconds (if needed) and that you just release the keys at exactly the check time instead of the rest of the 0.1s is not impossible, but a really small chance.
var time_since_last_check = 0.0
var check_interval = 0.1
...
time_since_last_check += delta
if time_since_last_check >= check_interval:
if fChangeAnimState() == true: #checks if its necessary to update animation
...
time_since_last_check = 0.0 #time reset
And well, its of course no perfect solution, but it does the job more or less^^
But thanks for the help. Now I know I have to be more specific next time