-
-
Notifications
You must be signed in to change notification settings - Fork 22.5k
Allow CollisionShape nodes to be indirect children of bodies #77937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
e635433
to
e195156
Compare
85806bc
to
f030b96
Compare
f030b96
to
9f2b977
Compare
What is the workaround for Recreate the node? |
@fire Changing the transform and changing it back would work. Or maybe we should expose |
Can't you use the NOTIFICATION_TRANSFORM_CHANGED? |
@fire Checking the global transform would cause it to update when the body moves, which would be every frame for some bodies. |
9f2b977
to
1fe74ed
Compare
ceb3567
to
6b76f08
Compare
Was there a bandaid for |
@fire
|
6b76f08
to
063656f
Compare
103eed7
to
0afba68
Compare
Recently, I encountered a blocker because I need to make some of my collision sets into 'Prefabs,' so I don't have to modify them repeatedly for the same changes. However, collisions must be direct children of bodies, making this setup impossible. This limitation is hard to swallow, as nearly all the engines I've encountered allow similar setups. Regarding the NOTIFICATION_TRANSFORM_CHANGED issue that @reduz mentioned, I have two ideas:
|
@ShirenY Note that there is already a As for the first idea, that's a good idea. We can skip all calls into the physics server if the relative transform is unchanged by caching it and comparing to the cache. |
Yeah, that's exactly what 2nd solution trying to promote. Currently node only can recieve NOTIFICATION_LOCAL_TRANSFORM_CHANGED from itself (AFAIK, is it?). What I'm trying to say is make NOTIFICATION_LOCAL_TRANSFORM_CHANGED a signal like visibility_changed, so that anyone else who is interested can listen to it. So that the shape can listen to all the nodes between it and the body. |
1d7f169
to
1ee8923
Compare
1ee8923
to
40590ee
Compare
40590ee
to
53e6fef
Compare
53e6fef
to
64a5d59
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested locally (rebased on top of master
04692d8), it works as expected with the following scene configuration:
Testing project: test_pr_77937.zip
In comparison, without this PR, none of the physics interactions work in the above testing project.
Code looks good to me.
Transform3D transform_to_col_obj = _get_transform_to_collision_object(); | ||
if (transform_to_col_obj == transform_to_col_obj_cache) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't an exact comparison like this still cause this cached transform to be invalidated quite often just by the nature of floating-point precision?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the transforms are exactly the same, then multiplying them will result in the exact same outputs. Within the same machine (not including network stuff), floating-point math is deterministic. If the float is slightly off due to precision issues, it will always be off by the exact same amount when the calculation is repeated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, somehow I thought the transform included that of the collision object, which it obviously doesn't, but even then you'd end up invalidating it just by virtue of the object moving around, so my concern never made much sense anyway.
Nevermind. :)
It's been a while but now I got 2 PRs to add something similar to my module, because I have nodes that need the same thing (not the physics part specifically, but rather the pattern of having child nodes that affect a common ancestor when transforms change). Today I wrote up a deeper post about how I would handle the transform notifications Zylann/godot_voxel#555 (comment) |
64a5d59
to
ce8dcc8
Compare
ce8dcc8
to
8f614ab
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works as expected, and is just what I need for my project, so thanks!
It made me wonder though, would it be helpful to have a NodePath to choose which ancestor PhysicsBody
the CollisionShape
affects? That way, users can have more flexibility over their scene designs.
8f614ab
to
7da7d4b
Compare
@lyuma is this still an issue? |
7da7d4b
to
1bbfb9b
Compare
1bbfb9b
to
f5870df
Compare
Any ETA on this one? This and #106048 are essential on a couple projects as they would greatly improve my workflow |
EDIT: Note that when this PR was first opened there were some caveats, but those have been resolved now. It should now be fully working including supporting when any node in the tree updates its transform, and should be fast.
Implements and closes godotengine/godot-proposals#535
This PR allows CollisionShape2D and CollisionShape3D nodes to be indirect children of bodies (CollisionObject2D and CollisionObject3D). A shape can only be connected to one body.
This is a highly demanded feature, see the discussion in godotengine/godot-proposals#535, #2174, godotengine/godot-proposals#1049, godotengine/godot-proposals#4559, godotengine/godot-proposals#5746 and https://ask.godotengine.org/31701/possible-rigidbody-have-colliders-that-not-direct-children.
Recently, Eoin from Microsoft has convinced me here that this is a vital feature. While I did debate with him about whether that's something worth standardizing... in terms of just whether the feature is good, I agree with him full stop, I don't see any reason to not have this. It just seems like a universally good idea.
The current code has the CollisionShape(2D/3D) looking for the CollisionObject(2D/3D) by running
get_parent()
and casting it to CollisionObject(2D/3D). So I made this a loop in the case that this cast fails, continue going up the tree until a body is found. All the code in CollisionObject(2D/3D) already works with a cached body reference and notifies it when things about the shape change like the transform.Production edit: closes godotengine/godot-roadmap#43