Creating a slow motion effect inside an area node?

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

I’m using a custom time scale variable and an Area3D to recreate the time stop power in Quantum Break, it’s working with kinematic bodies as they move using move and slide, however such function doesn’t exist in rigidbodies…

Is there a way to change and store the velocity of a rigidbody and reapply after the effect ends?

I think this would be quite complex, I believe you would need to change the applied forces on the rigid body and even then you may find it spins at a normal speed so you might have to play with the torque etc.

The documentation is here if it helps

RigidBody2D — Godot Engine (stable) documentation in English

I have never tried it before so somebody else may have a bit more experience with what you are trying to do.

Gluon | 2022-07-10 00:06

Yeah after messing around i found that this is quite complex, maybe i just play with both the damp values and reaply the speed after.

Niko | 2022-07-10 13:11

Have you considered using kinematic bodies? I dont know exactly what your game is but it would be easier with those. You could use area 2d’s with a function attached to the body entered signal to control their actions when they hit the ground or another object but this could end up being more complex in other ways depending on what your game is exactly.

Gluon | 2022-07-10 13:16

Using kinematic bodies could be easier to implement and control, if i did know how to make them interact with each other pushing and rotating other instead of being static.

Them multiplying their move speed, animation rate and timers with a variable would create the illusion.

Niko | 2022-07-10 16:31

:bust_in_silhouette: Reply From: Inces

Function integrate_forces() of rigid bodies uses stateargument under the hood, You can access it from within this function. It contains information about current movement whereabouts and a time flow of physicsserver.
for example :

func integrate_forces(state) :
         var speed = state.linear_velocity.length()
         var time = state.step

https://docs.godotengine.org/en/stable/classes/class_physics2ddirectbodystate.html#class-physics2ddirectbodystate

I guess You can try to read current speed and experiment with adapting damp, mass or friction when in area. Perhaps there are easier ways. Are You moving your bodies with apply_forces or apply_impulses ?

Im using rigidbodies for moving around simple boxes and throwing balls around, maybe when the bodies enter the area I store their speed and lerp the damp value to a higher number, them revert the damp and apply the impulse.

I could use kinematics for this but i don’t know how to make them push each other.

Niko | 2022-07-10 13:10

So You are using passive rigid movement, this is going to be hard :slight_smile:
I wonder if it is possible to override state. Maybe You could try something like multiplying state.step by 0.5 when collision is occuring

Inces | 2022-07-10 14:44

The physics step is a getter only property so it’s not possible to change it’s value like with engine.time_scale, instead multiplying linear and angular speed by the slow factor variable could do the trick, the problem is to make it travel the same distance and path.

Niko | 2022-07-10 16:13

After some experiments I managed to slow down the speed by lowering gravity and increasing the mass, it’s like the body is falling in half speed but manteining his path, however this only works with vertical speed because increasing drag changes the distance the object travels…

Niko | 2022-07-10 16:52