|
|
|
 |
Attention |
Topic was automatically imported from the old Question2Answer platform. |
 |
Asked By |
trailqul |
I’m new to godot, but I’m having a problem with something I thought would be simple. I have a ball that is falling off the screen. When it falls off the screen, I want to emit a signal that it has fallen. Then I want to place the ball back into its initial position and let that flow continue repeatedly. I thought that the visibilitynotifier2d would be the right way to do this, but when the ball exits the screen, the signal that it has exited the screen repeats indefinitely and resetting the position of the ball doesn’t seem to stop the signal. This consequently results in the ball just flickering in its starting position.
extends RigidBody2D
signal damage
var initialTransform
func resetBallPosition():
set_transform(initialTransform)
func _ready():
initialTransform = transform
func _on_visible_on_screen_notifier_2d_screen_exited():
print("ball fell!")
damage.emit()
resetBallPosition()
What am I missing from this little task?
|
|
|
 |
Reply From: |
trailqul |
Okay, after diving into a lot of little bits of information, I managed to piece together a solution that takes a different approach. For a RigidBody, you can’t just change the position because the physics simulation isn’t happy with that. You need to use _integrate_forces(state)
and use the state’s position. Here is the updated code that works
extends RigidBody2D
signal damage
var initialTransform
func reset_ball(state):
# You need to reset the forces that you don't want to maintain after
# resetting the position.
linear_velocity = Vector2.ZERO
angular_velocity = 0
state.transform = initialTransform
func _ready():
initialTransform = transform
func _integrate_forces(state):
if position.y > get_viewport_rect().size.y:
damage.emit()
reset_ball(state)
|
|
|
 |
Reply From: |
crossbito |
Hi!
Here is a solution to your problem:
extends RigidBody2D
signal damage
var initialTransform
var resetTransform = false
func _ready():
initialTransform = transform
func _on_visible_on_screen_notifier_2d_screen_exited():
print("Ball fell! ", linear_velocity)
self.set_axis_velocity(Vector2.ZERO)
damage.emit()
resetTransform = true
func _integrate_forces(state):
if resetTransform:
state.transform = initialTransform
resetTransform = false
Now, why didn’t your code work? Because RigidBody2D calculates forces on its own, and those forces are applied to its transform (position, rotation, etc). So, RigidBody2D reads that data and modifies it on its own. When you change the transformation, RigidBody2D does it too, overwriting what you did to the object.
To do it safely, you have to modify the properties of the RigidBody2D in _integrate_forces. This function is for that purpose. state represents the current state of the object, and you can change the transform, position, etc., there.
When you try this code, you will also see that here I only reset the transform, but it would be useful to reset the speed of the object because the object still has the speed gained from gravity.
To solve that, you can modify the function as follows:
func _integrate_forces(state):
if resetTransform:
state.transform = initialTransform
resetTransform = false
state.linear_velocity = Vector2.ZERO
I hope this helps!