Reputation: 20457
I've created a simple scene with a polygon that should wander around randomly. On a timer timeout, it should pick a random direction and velocity, rotate to face that direction and move in that direction.
However, what's actually happening, is that the object rotates briefly, but then snaps back to a rotation of 0.
This is how the scene is constructed:
The root node is a RigidBody2D.
This is the code attached to the root rigid body node, connected to the timer timeout:
func _on_direction_timer_timeout():
var direction = randf_range(-PI, PI)
var velocity = Vector2(randf_range(150.0, 250.0), 0.0)
self.rotation = direction
self.linear_velocity = velocity.rotated(direction)
If I only have the self.linear_velocity
line, then the polygons just slide around randomly, as expected. If I only have the self.rotation
line, then the polygons stay in place, but change to face random directions, as expected.
But with both these lines, the polygons momentarily rotate to face the direction, but then flip back to a rotation of 0.
This is what it looks like:
I tried adding a process function:
func _process(delta):
print(self.rotation)
And that always reports 0, which is consistent with the behaviour I'm seeing, but I don't understand why it's losing it's value.
Upvotes: 2
Views: 427
Reputation: 1729
My guess is, that the rotation is one of the attributes which are calculated by the physics engine every process step, which overrides your manual change after the timer tick.
Instead what you can do, as long as you don't call it every frame, is using the look_at() method:
func _on_direction_timer_timeout():
var direction = randf_range(-PI, PI)
var velocity = Vector2(randf_range(150.0, 250.0), 0.0)
var target = velocity.rotated(direction)
look_at(global_position + target)
self.linear_velocity = target
If this should also lead into unexcepted behaviour: In the documentation is a example how to create a look at behaviour for RigidBody3D. This might be tweekable for Rigidbody2D, too. Link here
Upvotes: 0