0 votes

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 moveandslide().
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
in Engine by (21 points)

2 Answers

+3 votes
Best answer

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 :-)

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

by (495 points)
selected by

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

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

It now looks natural, so nice :D 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)
0 votes

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.

by (588 points)
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.