Godot: RigidBody2d Strange physics behavior! its look like soft object!

Created on 22 Jan 2019  路  8Comments  路  Source: godotengine/godot

Godot version:
Godot Engine v3.1.beta2.official

OS/device including version:
Ubuntu 18.04.1 LTS

Issue description:
Check the uploaded GIF, Rigidbody2d object look like soft body and squeeze against static body. see bottom block. Is it expected behavior?

ezgif com-video-to-gif

Here is zip archive of same demo project
Stack.zip

archived bug physics

Most helpful comment

This is a problem with boxes and has been going around since a while, it needs a rewrite of a good part of the 2D collision code. I will work on it after 3.1 is out and is part of my roadmap for 4.0

All 8 comments

Now give it a mesh and call it a feature!

This is a problem with boxes and has been going around since a while, it needs a rewrite of a good part of the 2D collision code. I will work on it after 3.1 is out and is part of my roadmap for 4.0

In fact i think there is a similar issue opened around

A have read the errors for you.

extends Node2D

var scenePlayer=preload("res://Character.tscn");
func _ready():
    addPlayer()

func addPlayer():
    var player=scenePlayer.instance()

"""
E 0:00:02:0971   Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead
  <C Source>     servers/physics_2d/physics_2d_server_sw.cpp:633 @ body_set_mode()
  <Stack Trace>  Game.gd:8 @ addPlayer()
                 Game.gd:14 @ playerDroped()
                 Character.gd:25 @ _on_RigidBody2D_body_entered()
"""

    player.position=$Position2D.position
    player.connect("playerDroped", self, "playerDroped")
    add_child(player)

func playerDroped():
    addPlayer()


-------

extends RigidBody2D

signal playerDroped()

func _physics_process(delta):
    if Input.is_action_pressed("ui_left") and not Input.is_action_pressed("ui_right"):
        linear_velocity.x-=8
    elif Input.is_action_pressed("ui_right") and not Input.is_action_pressed("ui_left"):
         linear_velocity.x+=8
    elif Input.is_action_pressed("ui_down") and not Input.is_action_pressed("ui_up"):
         linear_velocity.y+=4
    else:
        linear_velocity.x=0

func _on_RigidBody2D_body_entered(body):
    self.set_physics_process(false)
    self.mode=MODE_STATIC

"""
E 0:00:02:0971   Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead
  <C Source>     servers/physics_2d/physics_2d_server_sw.cpp:633 @ body_set_mode()
  <Stack Trace>  Character.gd:18 @ _on_RigidBody2D_body_entered()
"""

    self.gravity_scale=10
    self.linear_velocity=Vector2(0,0)
    self.angular_velocity=0
    self.contact_monitor=false

"""
E 0:00:02:0971   Can't disable contact monitoring during in/out callback. Use call_deferred("set_contact_monitor",false) instead
  <C Source>     scene/2d/physics_body_2d.cpp:911 @ set_contact_monitor()
  <Stack Trace>  Character.gd:22 @ _on_RigidBody2D_body_entered()
"""

    self.contacts_reported=0

    emit_signal("playerDroped")

This works as intended:

extends RigidBody2D

signal playerDroped()

func _physics_process(delta):
    if Input.is_action_pressed("ui_left") and not Input.is_action_pressed("ui_right"):
        linear_velocity.x-=8
    elif Input.is_action_pressed("ui_right") and not Input.is_action_pressed("ui_left"):
         linear_velocity.x+=8
    elif Input.is_action_pressed("ui_down") and not Input.is_action_pressed("ui_up"):
         linear_velocity.y+=4
    else:
        linear_velocity.x=0

func _on_RigidBody2D_body_entered(body):
    self.set_physics_process(false)
    #self.mode=MODE_STATIC
    set_deferred("mode",MODE_STATIC)
    self.gravity_scale=10
    self.linear_velocity=Vector2(0,0)
    self.angular_velocity=0
    #self.contact_monitor=false
    call_deferred("set_contact_monitor",false)
    self.contacts_reported=0

    emit_signal("playerDroped")
----
extends Node2D

var scenePlayer=preload("res://Character.tscn");
func _ready():
    addPlayer()

func addPlayer():

    var player=scenePlayer.instance()
    player.position=$Position2D.position
    player.connect("playerDroped", self, "playerDroped")
    add_child(player)

func playerDroped():
    #addPlayer()
    call_deferred("addPlayer")

Here it possibly catches an another gles2 bug

Loading resource: res://Floor.tscn (cached)
ERROR: _gl_debug_print: GL ERROR: Source: OpenGL    Type: Error ID: 2   Severity: High  Message: GL_INVALID_FRAMEBUFFER_OPERATION in glDrawArrays(incomplete framebuffer)
   At: drivers/gles2/rasterizer_gles2.cpp:134.
ERROR: _gl_debug_print: GL ERROR: Source: OpenGL    Type: Error ID: 2   Severity: High  Message: GL_INVALID_FRAMEBUFFER_OPERATION in glDrawArrays(incomplete framebuffer)
   At: drivers/gles2/rasterizer_gles2.cpp:134.
...

@capnm, you may correct but this line added for testing purpose.

self.mode=MODE_STATIC

So set_deferred("mode",MODE_STATIC) not needed at all because this will make body static and stack will never drop.

Now try with remove this line
set_deferred("mode",MODE_STATIC) and test, You would get same soft body issue.

set_deferred("mode",MODE_STATIC) and test, You would get same soft body issue.

I think even then it looks ok:

peek17

Edit: ok, it's a bit soft if you put the dice aside or move faster;) but it's exactly the same as in Godot 2.x.

Yes correct in all godot version has same behaviour. Hope it will fix in godot 4.

Apparently the OP (turning into soft body) was a script error. The jittery collisions for many 2D collision objects is a duplicate of #2092. Will need breaking compatibility to be fixed, so it's on the 4.0 milestone.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kirilledelman picture kirilledelman  路  3Comments

gonzo191 picture gonzo191  路  3Comments

Spooner picture Spooner  路  3Comments

mefihl picture mefihl  路  3Comments

testman42 picture testman42  路  3Comments