Rotating a wheel properly (angular velocity)

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

I have a player character, which is a wheel and a KinematicBody2D. This wheel rotates based on the linear velocity, the same velocity I use in my move_and_slide().
I guess I’m just rusty when it comes to trigonometry. I have been fiddling with variables to get it to look like it’s rotating, but I want it to rotate properly. How can I do that?
My game has floor tiles that are 64 pixels wide. My player sprite is also 64 pixels wide, so those cancel each other out.
Here is my code. What formula can I use instead of the janky one in my rotation-variable?

func get_rot():
var d = 64
var circumference = d * PI
var rotation = (linear_vel.x / circumference) / (2*PI) # This is wrong
var rotate_amount: float

if linear_vel.x <= 0:
	rotate_amount = -abs(rotation)
else:
	rotate_amount = abs(rotation)

return rotate_amount
:bust_in_silhouette: Reply From: scrubswithnosleeves

I don’t really understand your function here, but if I understand what you are trying to do, you want the wheel (KinematicBody) to rotate proportional to the linear velocity.

I would just use the rotate() function. This will rotate the object by the amount (float in radians) given in the argument. Call this in the _physics_process() ofc. I would probably recommend rotating the sprite only and not the entire kinematic body unless that is important to you. just do $sprite.rotated(amount). for amount, I would do your velocity/x * delta. You will have to play around with what number you will substitute for x, might even be 1 idk how fast you want this thing spinning.

Also, rotation is a property of almost every node in Godot, so you shouldn’t name any variables rotation as you did here as that will shadow it.

:bust_in_silhouette: Reply From: AndyCampbell

Hi - I think you want to know how to calculate the required angle of rotation from the linear velocity, right?

If you work in radians that works easier for Godot

1 rotation = 2 * PI radians.
So, to calculate rotation in radians you need
(linear_vel.x / circumference) * 2 * PI

You were ALMOST correct :slight_smile:

So, with your figures:
D = 64, so circumference = 64 * PI = 201
if linear_velocity.x = 50, that is
50/201 * 360 = 89.5 degrees
or
50/201 * w PI = 1.56 radians

That’s exactly what I meant! Thank you so much. Multiply rather than divide, got it! :slight_smile:

asgerregsa | 2020-11-12 11:47

I should have added, you need to take care of the timing of the frame, so multiply you rotation by delta which is provided as an input to the _process function

AndyCampbell | 2020-11-12 11:56

It now looks natural, so nice :smiley: I’ll post the working code here, in case anyone wants to do the same:

func _physics_process(delta: float) -> void:
  movement(delta)
  move_wheel(get_rot(delta))

func get_rot(delta):
  var d = 64
  var circumference = d * PI
  var rotation = (linear_vel.x / circumference) * 2 * PI * delta
  var rotate_amount: float

  if linear_vel.x <= 0:
	rotate_amount = -abs(rotation)
	return rotate_amount
  rotate_amount = abs(rotation)
  return rotate_amount

func move_wheel(rotate_amount):
  $PlayerSprite.rotate(rotate_amount)

asgerregsa | 2020-11-12 12:15