Changing a RigidBody2D from Rigid to Static, but only if not falling anymore?

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

Hi all,

  • I have a little lemming.
  • I blow him up.
  • He flies through the air (as a rigidBody2D set to Rigid).
  • He lands on the ground (or another little lemming) and settles into his rest spot.

This is all well and good. But after about 200 lemmings on screen things are getting pretty bogged down even on a multi core i7 with 16Gig of RAM so I don’t think my phone will handle it.

I’ve tried:

  • setup a timer that counts down as a 1 shot from 4 seconds
  • when timer finishes, change mode to Static

This works, it’s really quite good. EXCEPT for those times that a lemming is still falling about. Then I have them sitting in mid air. This is not good. :slight_smile:

So! Does anyone have any suggestions as to what I can do? I was thinking of checking for collisions perhaps? If the 4 seconds is up, is lemming touching anything? If so turn on Rigid otherwise count down another 4?

What do you think would be the best thing to do here?

Thanks so much

This isn’t related to your floating dead soldiers, but could help with your performance…:

I noticed in the code from your other post that you are calling .new(self) each time the state changes. Are you re-using the states you already created or are you making a new state each time? Since your inner classes are inheriting from “Object”, you are responsible for memory management.

Since the life expectancy of a solider is not very long, you may want to refactor your state machine to create all of the states up front and then switch between them as needed.

Something else you may want to consider is re-thinking the collision shapes of the dead soldiers. If you want the corpses to pile up vertically, then you may want to merge collision shapes so you don’t have weird triangle on triangle things going on. It could be problematic for the soldiers to climb over those. If you don’t want them to pile up vertically, then you could remove the dead collision shape and just put an area 2d. As live soldiers enter that area (walk over them), you could have the corpse start decomposing(mutilating from being stepped on) until it disappears. Then, you may not even need to make the corpses a physics body.

2D||!2D | 2018-05-11 15:32

:bust_in_silhouette: Reply From: SIsilicon

Ok. Try this.
Rigid bodies have a signal called body_entered. You could use that as long as contact_monitor is true, and contacts_reported is greater than one. So something like-

_on_body_entered(body):
    mode = MODE_STATIC #Or something else that you want to do.

Vote n’ Select :slight_smile:

FYI, when two lemmings collide in the air before hitting the ground, they’ll stay collided in the air unless you have their collision layers/masks configured to not hit each other.

markopolo | 2018-05-11 16:15

That’s where the obj parameter of the signal can be useful.
What you can do is run a condition inside the function so that if the colliding object obj is the ground, or not another lemming, then you go static.

SIsilicon | 2018-05-11 17:13

mmmm this is good and this is tricky.

I want it to settle into position first, so it needs to settle into position first, then change to rigid only if it’s touching another dead lemming or the ground.

Imagine it gets blown up and flies across the screen good fun so if I change it to rigid as soon as it hits a dead lemming it may stick to the side of a wall of dead lemmings. Just hanging in the air. Creating a ledge.

I need it to fall first, settle and then turn rigid.

Robster | 2018-05-11 22:54

Ok then.

  • cracks knuckles
    Try this. Give each lemming a timer node that starts whenever they collide with the ground. When it times out, then it can go static. So you must have another function to connect to the Timer’s timeoutsignal.
_on_body_entered(body):
    if body == ground and $Timer.is_stopped(): 
        #ground is reference to ground node/scene.
        $Timer.start()

_on_Timer_timeout():
    mode = MODE_STATIC #Or something else that you want to do.

Not necessary, but make sure one_shot on the timer is enabled.
And set the wait_time to however long you’d like.

SIsilicon | 2018-05-12 00:44

And I noticed that your comment used the word rigid. I’m assuming that’s a typo.

SIsilicon | 2018-05-12 00:45

Thank you for that. I was thinking similar but I wonder if it will still have issues of a random lemming that may still be falling etc. I guess I can play with the timing. I’m set to 4 seconds in earlier tests so I could play with that. Watch this space, I’ll give it a go and see what happens.

Robster | 2018-05-13 23:31

OK I think that’s done it, or close enough for the game’s purposes. I’ll be sure to post updates as it’s getting closer to done. Thanks for your help.

Robster | 2018-05-14 05:45