Can not disable CollisionShape2d with: $CollisionShape2D.disabled=true in Godot 3.1.2

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

Why doesn’t disable the Collisionshape2d in code: “$CollisionShape2D.disabled=true”. The collision shape is attached to a KinematicBody2. I did it exactly as shown in a tutorial, except that in tutorial Godot 3.0 was used.

:bust_in_silhouette: Reply From: Xtremezero

For some reason the following code doesnt work:

$CollisionShape2D.disabled = true

, however using the following works perfectly:

get_node("CollisionShape2D").disabled= true

you can also visualize the collisions from the Debug → Visible Collision Shapes … when it’s disabled it turns to grey

I suggest you check in bugs list, and do a bug report if no one reported it earlier and not use $CollisionShape2D.disabled till it’s solved

Thank you for answer but it still doesn’t work. It is strange that the collision shape does turn to grey but it is actually not disabled because can’t pass through it.

cristixxx | 2019-12-16 18:38

hmm… very weird , do you mind uploading the project file to any storage cloud and share the link so I can check it in my side?

Xtremezero | 2019-12-16 20:07

Hello! Here is the link to the project: https://drive.google.com/drive/folders/1cuEmOi0N-xyoA1ur4jAvBZoLnW6oSbul

cristixxx | 2019-12-17 18:40

the link is private, cant open it

Xtremezero | 2019-12-18 00:14

https://drive.google.com/folderview?id=1cuEmOi0N-xyoA1ur4jAvBZoLnW6oSbul
Maybe now will work.

cristixxx | 2019-12-18 09:52

:bust_in_silhouette: Reply From: Phil Rukin

I’ve encountered the same issue in Godot 3.1.2 and used layers as a workaround, but this seems to be fixed now in Godot 3.2 !

:bust_in_silhouette: Reply From: jgodfrey

Try this:

$CollisionShape2D.set_deferred("disabled", true)

Which waits until it’s “safe” to actually disable the collision shape.

I had the same issue with my project and calling

$CollisionShape2D.set_deferred("disabled", true)

resolved my enabling/disabling collision shape issue. Thanks

jickingx | 2020-02-21 01:50

Thank’s!!! You really help me)

robodraif | 2020-03-07 16:23

It really helps me!

yikescloud | 2020-05-05 17:28

Thank you for this,

The following code just doesn’t work and it’s the logical and common way to do this.

get_node("CollisionShape2D").disabled= true
$CollisionShape2D.disabled = true

can someone explain why this set_deferred thing works? The reason to disable it just because it’s “safe” just doesn’t make sense to me

flixbeat | 2020-10-29 16:57

That’s because, to my understanding, the physics engine makes calculations for every frame based on collision shapes and other objects. If you suddenly disable a collision shape, it may interfere with the physics engine since it could be using the collision shape at that time. If you instead disable the collision shape when the physics engine is done with the calculations for the current frame using “set_deferred” or “call_deferred”, no conflict is going to occur. Thus, we call it “safe” to make such changes when the physics engine is idle. If you don’t respect that, you should be getting runtime errors.

nahiyan | 2021-06-24 16:18

Thanks, get_node("StaticBody2D/CollisionShape2D").set_deferred("disabled", false) worked for me :slight_smile:

steelx | 2022-08-02 05:05

:bust_in_silhouette: Reply From: Ras0922$$

Even I am working on the same project. Instead of disabling CollisionShape2D I just deleted it.
It doesn’t affect the scene but does the work.

$CollisionShape2D.free() 

You are a genius!
Thank you so much, I registered the account just to upvote and comment on your post
The other solution was working but I did not understand a word of it. I am just a beginner and I ran into so many problems when I searched for the solutions on google, all of them are like super high level and I couldn’t understand anything. Your solution is the easiest to understand, the most efficient and optimized.

Thank you so much Again!

Rajibkc76 | 2022-01-22 16:47

:bust_in_silhouette: Reply From: gozul

you actually can, I had the same problem you need to do:

“$CollisionShape2D.set_disabled(true)”

The “set” part is necessary, a bit confusing, I know.

What I would want to know is if there is any difference in doing it like this or with “set_deferred”.

This is incorrect. There is no property called set_disabled, so this will produce an error.

You can either do

$CollisionShape2D.disabled = true

or call the setter

$CollisionShape2D.set_disabled(true)

Although the former is standard practice; properties are directly accessible.

It may be you’re confused by the need to use set_deferred() when a property of a physics object needs to be changed during the physics processing step. Since that’s not allowed, the change must be deferred to the end of physics processing.

set_deferred takes two arguments: the property name, and the new value:

$CollisionShape2D.set_deferred("disabled", true)

kidscancode | 2021-02-02 18:48

Oh, I’m sorry I did meant to write:

“$CollisionShape2D.set_disabled(true)”

I edited my comment to avoid confusion for future readers. That was me typing it wrong as I am using it in my game xD

But I am still not sure of “set_ deferred”, is it better to use it than “set_disabled” in general. Or you should choose one or the other depending on if you need it sync to physics or not?

gozul | 2021-02-06 13:10

They’re the same thing, it’s just that you’re not allowed to disable collision during the physics step - if you do, you’ll get the message that you need to defer it.

kidscancode | 2021-02-06 17:56