Help implementing a "position jitter" in 3D movement

Godot Version

4.5

Question

Hi! In our game, one of the core mechanics is to move while injured. This translates in 3 necessities:

  1. The player character has to have unstable movement, through some kind of “jittering” in their position that matches the animation.
  2. The speed of the character must change at irregular intervals.
  3. The camera’s orientation must remain the same, but the position should move alongside the player.

In other games, if you are injured you just move slower with some screen effects. In our case, because the main character is injured the whole game, we need to expand on this. My first solution to this was to “brute force it”. (It’s not very clean but I hope you get the idea)

This is the setup:

The main script is in the player node, being the “SophiaSkin” one just for animations. The position you could see in the video is being applied to the root Player node.

I have a Vector3 variable position_jitter that’s being animated in the AnimationPlayer node, and the state machine executes and cleans the variable depending on the state. That’s how I brute force the “position jitter” effect.

This is the relevant code:

func _physics_process(delta: float) -> void:
	state_machine.physics_process(delta)
	
	# Character's orientation
	var raw_input := Input.get_vector("left","right","up","down") # player's input
	
	var forward := camera_pivot.global_basis.z 
	var right := camera_pivot.global_basis.x 
	
	# Movement's direction
	var move_direction := (forward * raw_input.y + right * raw_input.x) 
	print(raw_input)
	move_direction.y = 0.0
	move_direction = move_direction.normalized()

...

	if raw_input.y > 0 or raw_input.y < 0:
		position.x += position_jitter.x
	
	if raw_input.x > 0 or raw_input.x < 0:
		position.z += position_jitter.z
		
	move_and_slide(

Finally, the position_jitter variable has the z and x animated to go from -0.05 to 0.05, very similar to a sine curve but controlling the rhythm, so to speak.

As you can see from the video, is very far from perfect. If the input is diagonal it starts to do that weird movement backwards, and if I’m using a controller the positions is more messed up. The problem is that the position_jitter variable is so brute forced that it only works in (1,0) or (0,1) inputs, the moment I have something in between it stops working.

So, here is the question: how would you approach this? Some months ago I posted about drunken movement and this is how far I went with the idea. I either need a way to make position_jitter more flexible, or an entire new way of approaching the injured gameplay. I’m open to both!

Why simply not oscillate along the right direction?

Could you elaborate, please? I don’t think I’m following.

The right is for orientation, and changes the orientation of the character. I’m looking to change the position itself.

Ok, looking at your code what I really meant was perpendicular to move_direction

You want some movement distraction but not too unpredictable so it doesn’t frustrate the player. If the player moves down the move_direction add the periodic sine-like jitter along the direction that’s perpendicular to that. That way they’ll “wobble” but still generally move in the wanted direction.

Hello! Sorry for my late answer. I actually I implemented it in my game and you were right! It did wonders. I’m new to programming in general so I just discovered the world of vector math haha

Thank you!

1 Like

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