Resetting a rigidbody's state after an impulse and gravity are applied

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

Hello,

I am working on a planetary orbit puzzle game. I have a RigidBody2D called “guy” that is fired from a starting orientation by applying an impulse to it in the _integrate_forces() function. When you fire guy, he flies around the screen being affected by various Area2Ds with point gravity enabled.

Given certain conditions, the level is reset to the beginning and you can try again. I am finding that I cannot get guy to be in the exact same orientation (mainly rotation) when I reset him. He is always in the last orientation that the engine applied to him when the physics were running.

How can I save guy’s state at the beginning and reset to it to that state when I need to?

Thanks,

Judd

:bust_in_silhouette: Reply From: Xrayez

Hmm I think I’ve recently had similar problem to yours and I think it might work for your use case:

var pending_rotation = []

var rot setget set_rotation, get_rotation

func set_rotation(p_angle):
    pending_rotation.append(p_angle)

func get_rotation():
    return rotation

func _integrate_forces(state):
    for rot in pending_rotation:
        var reset_rot = Transform2D(rot, state.transform.origin)
        state.transform = reset_rot
    pending_rotation.clear()

You might also need to reset linear_velocity and angular_velocity after respawn using the same state, and you can change position and scale in a similar way, or you can just save the initial transform and restore it altogether.

Here is what I am doing now - I am mystified about why this does not seem to work.

func _remember_starting_state():
    _initial_transform = self.global_transform
    print('initial rot: ', global_rotation)

func _reset_to_start(body_state): #reset everything to the beginning state
    print('resetting...')
    self.modulate.a = 0.0 #hide me
    
    self.global_transform = _initial_transform

It goes to the correct position, but the rotation is still wonky. Though it reports to be at 0 both when the level starts and when it gets reset. Maybe this is an issue with node parentage? It is very confusing though.

Judd Gledhill | 2018-08-09 21:17

The rigid body’s physics simulation will override existing transform properties of that body if you’d try to manually change it. While it does work (hopefully) for setting position for the body, it may not work for other properties like rotation and scale, and you don’t really want to disrupt physics simulation that way. For that reason, it’s more safe to reset body’s transform inside _integrate_forces() where you apply impulses to your character.

It may be a bug because I couldn’t rotate the body as you described either via your method while it does work with position alone.

Xrayez | 2018-08-10 07:26