Open Diddykonga opened 1 year ago
Related to https://github.com/godotengine/godot-proposals/issues/2184.
I think this is too large a scope to be done for 4.0. We should only do minor adjustments from now on, or anything else will take too much time to bikeshed on.
I think this is too large a scope to be done for 4.0. We should only do minor adjustments from now on, or anything else will take too much time to bikeshed on.
That's fine I understand how late this is, and will take some time to bikeshed as you pointed out. Although hopefully for 4.1, as I believe that will be the last chance to do any compatibility breaking that this would require.
I think having static bodies as a separate is still very worthwhile... though I can't really remember the last time I actually used it. I just press the button that generates colliders for me.
I think having static bodies as a separate is still very worthwhile
StaticBody3D
: This node was incredibly simple and can be recreated with aRigidBody3D
and setting BodyMode toSTATIC
.
If this ^ makes something worthwhile, then we are doomed.
StaticBody3D: This node was incredibly simple and can be recreated with a RigidBody3D and setting BodyMode to STATIC.
I can't think of an engine where you DON'T have a StaticBody of some sort since it's so extremely common an use case. It saves users several clicks.
I can't think of an engine where you DON'T have a StaticBody of some sort since it's so extremely common an use case. It saves users several clicks.
While I still think that you are overthinking it, since they are many other nodes that you must setup first before they are proper for your use case.
Either way I digress and would suggest BodyMode be STATIC
by default when creating a RigidBody3D
.
This way if you spawn a million for some odd reason, they wont all be DYNAMIC
if you forget to set the BodyMode.
I think having static bodies as a separate is still very worthwhile
StaticBody3D
: This node was incredibly simple and can be recreated with aRigidBody3D
and setting BodyMode toSTATIC
.If this ^ makes something worthwhile, then we are doomed.
Watch your tone.
Firstly, yes, it most definitely does make it worthwhile, in a game development context, especially a game development context designed to be easy to access, quick and easy to start developing with. With such an argument, it could be said that VisibleOnScreenEnabler shouldn't be a class, either, because it's easy to set up using VisibleOnScreenNotifier as a base.
Secondly, there's one very important thing. StaticBodies are always static. They'll never not be static. Oftentimes, these nodes are unmoving, as well. It's a major open door for optimisation.
I agree with @Mickeon regarding StaticBody
. By having the body as a separate type to the RigidBody
then a user can have the assurance of single-use, that a scene using the StaticBody
won't just suddenly start acting dynamically out of the blue because somewhere the mode was changed. The same could be said for KinematicBody
and a DynamicBody
; they would each provide assurances that they won't suddenly start acting like the other because of one wrong flipped switch. Perhaps that is a pedantic worry, but Godot does aim to follow SOLID if I remember correctly.
It'd also be more intuitive for any new Godot user who is not versed in physics or industry terms to figure out and remember StaticBody
does not move, DynamicBody
is moved by physics, and KinematicBody
is moved by code. Rather than RigidBody
is the physics body for solid things, named after a term they may never have been exposed to, and has modes for not moving, moving by physics, moving by code, and whatever dynamic-locked connotates-- I never had to look into it to find out. So it makes sense to me to have those 3 subset bodies alongside the main RigidBody
.
What both of you are pointing out is that a StaticBody
is assumed to always be Static, but in reality the low-level Physics Body can be switched to either mode, so at any time an StaticBody
may be Dynamic.
Either a change to the low-level PhysicsServer for creating distinct body types and not allowing changes should be made or otherwise, this is not doing what you expect.
What I am suggesting is a change that more accurately represents the interface that the Nodes are built to expose to users in the Editor. I really can not understand the requirement for not changing a enum property on a Node you add to a Scene to get the functionality you want, as there are multiple examples of this throughout the Engine.
That is true, the argument on my end for single-use and presuming it is always static is admittedly a weak one. Though the having of StaticBody
and other nodes representative of RigidBody
nodes were less to be representative of the underlying system but rather useful abstractions of that underlying system for, albeit potentially minimal, ease of use in ways. There is definitely a valid argument for trying to expose the base physics server RigidBody
API only accurately. Though with my argument I feel that RigidBody
should be a node ideally for that reason; an accurate exposing of the physics API underlying for more complex uses, whilst the three nodes representative of RigidBody
's main modes are there for ease of use and shortcuts.
I still think it's easier and more intuitive for new users to have KinematicBody
, DynamicBody
and StaticBody
in addition to RigidBody
rather than just RigidBody
. For those unfamiliar with standard terminology, I noticed in my research on this topic-- primarily going through the Reddit poll for the RigidDynamicBody
rename-- that many who weren't exposed to prior terms through either education on physics or prior experience with game engines found RigidBody to be too specific to those specific realms of expertise to be immediately recognizable or memorable to them in relation to learning. So whilst maintaining the industry standard of having a RigidBody
for good reason it also makes sense to have the aforementioned trio of nodes to ease newcomers to game development by giving them more specific to their use nodes that can have better memory correlations.
However, having those three nodes are not a dealbreaker; I still consider this refactoring an improvement over the current organization regardless of what I suggested to potentially improve it. After considering what @Diddykonga has said in their messages; there ultimately isn't really much of ease of use boon, other than having them be potentially easier to learn as said in the prior paragraph. In regards to what @Mickeon said about optimization, is that actually possible considering that afaik StaticBody
is effectively just exposing the physics server RigidBody
in static mode? That is to say wouldn't any potential optimizations be already included in either way since they're both the same underlying thing? Or is it meant that StaticBody
would not need to contain any logic to make a kinematic, dynamic, or dynamic-linear mode work node-wise?
Optimizations for RigidBodies in Static BodyMode is done currently.
So you have the medium-level Nodes such as RigidBody
that I am suggesting, that simply expose the underlying low-level system/server that they are based on, which gives easier access to the general use cases the low-level system/server provides.
Then you have high-level Nodes such as CharacterBody
that further exposes a medium-level Node(or potentially low-level if no medium-level makes sense) to provide deep functionality for specific use cases.
All StaticBody
, KinematicBody
and DynamicBody
do is set BodyMode enum, they don't provide any other functionality as compared to CharacterBody
for example, which should be kept.
As for the teaching/learning aspect, I would agree although I'm not confident that Kinematic
is a very well known term either.
The way I look at it, is that the documentation for the Physics Bodies just needs to be improved to properly explain the hierarchy and systems in play, which I attempted to break down in the OP.
Hmm, yeah I'd say I overall agree with that. Especially the whole Kinematic
not being as well-known, issue; I noticed it too a few days ago and I've been trying to think of good solutions for it. Like, there are a few thoughts I've had on that.
KinematicBody
node that has some extra stuff compared to RigidBody
for stuff such as moving platforms with code; basically it's the one that has move_and_collide
and such simulated motion helpers. This is a bit unclear because of the fact that kinematic
may not be a well-known term potentially, and I guess one argument against it compared to 2 is that it may limit developer creativity.PhysicsBody
node reorganization and have such kinematic
/ simulated motion helper aspects be in the RigidBody
node so that everything is effectively kinematic
. This may make the most senseKinematicBody
a static and dynamic physics mode so that it can be used to move objects of both physics types with code. The only benefit of this over 2 is that you can potentially mix static and dynamic movement of the object for unique movable things, like a prop hunt mechanic-inspired game, though I have no clue how that could ever be cleanly implemented. This is more of a weak random idea that popped in my head and wanted to get out, highly unlikely this one is a good idea.1. 2. 3.
There really is only so much you can do with a Physics Body, so unless it was specifically a MovingPlatformBody
or something, that had a deep(?) implementation for specific use cases then maybe, although I am not 100% certain as to whether this should be a high-level node, since I am not sure how deep of an implementation you could provide that would require the code to be C++ for speed.
I have thought for awhile about introducing Engine Content into Godot, as it is one of the things that I miss from Unreal, where Engine Developers could provide Assets that come as part of the Engine, which the MovingPlatformBody could be a Scene that comes with the Engine Content, to be either used directly or learned from.
This is the plan currently, to move all Body-Wide helper methods to RigidBody
, and potentially in the future to PhysicsBody
, if we are able to figure out what all Rigid and Soft Bodys have in common.
This is basically a RigidBody
in Dynamic BodyMode, as a Dynamic Body can still be moved by the user, while also effected by the Physics Simulation. Although you must do it in _physics_process()
(?) or _integrate_forces()
, which isn't technically required for non-Simulated BodyMode's.
So, do we agree that DynamicBody
and StaticBody
should exist, presuming numerous others also agree, for teaching/intuitive reasons for beginners or those new to Godot? That there is no need for KinematicBody
since it should already be handled by RigidBody
, or potentially PhysicsBody
if applicable?
Personally, I disagree, simply because of how basic they are, and this type of thing really should be handled via good documentation + examples.
All types are covered by RigidBody
Node, which you can set it's BodyMode to be either a Static, Kinematic, or Dynamic(-Linear) Body.
Alright. Well to be honest that is fine. I can kind of see your point of view now, and the one I'd been arguing very well could've been biased and weak for reasons currently unknown to me given I am now not finding much of a solid argument on my side, in comparison to before, at this point. So presuming no one else actually has good reasons in regards to having those other bodies then I am at present fine with just RigidBody
.
For High-Level Nodes, to me it comes down to how much code/effort-in-editor would it take for me to recreate that Node if it didn't exist,
For example, CharacterBody3D
would be quite a bit of code and would also run slower in GDScript.
Where as, StaticBody3D
is the default RigidBody3D
(I believe Static BodyMode should be default), and DynamicBody3D
is a RigidBody3D
with BodyMode set to Dynamic. Which doesn't reach the threshold for Node-ification.
I find this proposed structure miiiiles more clear and therefore much more preferable than the current one in Godot4 Alpha14.
However I do have some problems with this proposal too, especially with defaults and behaviour:
Either way I digress and would suggest BodyMode be STATIC by default when creating a RigidBody3D.
This just sounds like a very bad idea, as it is super confusing: By default you expect a RigidBody
node to be able to move. Making it STATIC
by default is already confusing. Then allowing it to move under certain circumstances despite it being in STATIC
mode: super confusing and weird! This does not sound much better than what we have right now in Godot4 Alpha14.
I would expect RigidBody
to have default mode set to DYNAMIC
.
CharacterBody
is a misnomer! This node/mode will be used for way more than characters. If your goal is to make things less confusing, stop using that name! KinematicBody is well established for this type of behaviour, even outside of Godot or the games industry.
Imho, StaticBodies
(or RigidBodies
in STATIC
mode) have no business moving. That's why they are called "static"! In my opinion, they should be entirely passive. Rigid and Kinematic bodies can collide with them, but StaticBody
can't bulge.
KinematicBodies
(or RigidBody
in KINEMATIC
mode) imho has no business being moved by physics forces, that's the job of the RigidBody
DYNAMIC
node/mode.
The DYNAMIC_LINEAR makes no sense to me. If the only difference to DYNAMIC is the option to make it axis locked, why not simply expose this property to DYNAMIC
mode as it is right now in Godot3 RigidBody
? If there is some other reason why this extra mode exist I currently just don't see, I would rename it to DYNAMIC_AXIS_LOCK
, since this would actually describe what it does. DYNAMIC_LINEAR
sounds to me like forced linear acceleration, which this is not.
I think having a single node with very clearly defined modes which purpose does not overlap has a lot of benefits compared to the current Godot4 Alpha 14 system and even to the Godot3 system. Especially because this would allow to seamlessly switch an object from one behavior and type of user control to another.
@TrialDragon
By having the body as a separate type to the RigidBody then a user can have the assurance of single-use, that a scene using the StaticBody won't just suddenly start acting dynamically out of the blue because somewhere the mode was changed.
Being able to switch between distinctive single purpose modes at any time is exactly what is missing and what is only partially working in Godot3.
In Godot3 you already can switch between KINEMATIC
and RIGID
modes for RigidBodies
. The problem is you can't control the RigidBody
like you would a KinematicBody
, when the RigidBody
is in KINEMATIC
mode. Which makes is pretty almost useless for countless gameplay applications. Most predominantly for Ragdoll-Like behaviour. In Godot3 you can't simply switch between KinematicBody
and RigidBody
(for example in mid air flight, or when the player lost control of their character). You can only lock an axis, but you can't use the KinematicBody
move_and_...
methods.
Which means as a designer I can't switch between intentional-driven entity control and driven by physics simulation at will. The only option is to completely replace the whole entity (since the physics behaviour is usually done in the root node) with a different one, which is an invitation for all kinds of bugs and performance issues (you will have to make sure to enable and disable everything). If switching behaviour could be done with the same root node, this would make highly dynamic fun physics simulated gameplay combined with precise user input controlled gameplay a breeze compared to now.
However I do have some problems with this proposal too, especially with defaults and behaviour:
RigidBody
BodyMode can be either STATIC or DYNAMIC by default, I care not which, that is for others to discuss.
RigidBody
BodyMode could do without DYNAMIC_LINEAR, in favor of generic linear/angular axis-lock flags.
CharacterBody
makes sense, in that it is a specific implementation of a RigidBody
in KINEMATIC BodyMode, that is intended for use with Characters. This has support for things that a Character would want, and that other KinematicBody use-cases might not need, it is high-level and meant for specific use cases where it fits. If move_and_slide()
is what you feel should be base, then that could be discussed.
We have discussed the general state of the physics nodes in the bikeshedding meeting. We've agreed to drop the Dynamic
qualifier from both rigid and soft bodies, so that the terms match the terminology that is most familiar across different engines. We can still have "dynamic" as a keyword in the documentation to help look up the relevant methods, once we introduce the keyword system to the documentation.
We don't plan to make any further changes to the physics nodes for 4.0. All previous discussions had a lot of people happy and unhappy about changes, so it doesn't look like there can be a universally good stack that satisfies everyone. Or at least one hasn't been found yet. Maybe in Godot 5... But for now, changing it back and forth, especially so close to beta, doesn't look like a good idea. Especially given we don't have many physics maintainers at the moment to make a good educated decision for the area.
I won't close the proposal, so feel free to deliberate further, but we won't be considering more structural changes for Godot 4.
we won't be considering more structural changes for Godot 4.
Sad to hear, I guess I will be back for Godot 5 then.
CharacterBody
is a misnomer! This node/mode will be used for way more than characters. If your goal is to make things less confusing, stop using that name! KinematicBody is well established for this type of behaviour, even outside of Godot or the games industry.
Been looking for the proper place to say this. As someone starting to learn directly with 4.0 this is not only very confusing (As with that, not a single node is named KinematicSomething
), but also incredibly opiniated in the worst possible way. Things should be named according to what they do not according to whatever someone thinks it should be used for.
Not experienced enough in the engine to debate on which bodies there should or should not be, but this name definitely has to go at some point.
I am all for going with this or a similar approach for the structure, looks very simple to understand. Especially if it lets you easily change body modes and it just working without having to write much extra code for separate modes. Could be useful for making things like simple grapple hooks on kinematic characters using joints.
DYNAMIC_LINEAR: PVI, PFI, Moved by PS and user-code, rotation locked for use with Characters
I feel like just adding a separate bool that lets you lock rotation is a more intuitive approach
Reading the discussion, it seems like the main problem people have with this approach is the possible unintuitiveness of the naming and proposed default settings, and that some people would prefer to have separate nodes just to save a few clicks when creating them. This could potentially be solved by adding a node preset system (something I've been planning to make a proposal for), and renaming the node to a more overall term like PhysicsBody, with Rigid/Kinematic/StaticBody being its presets.
It would be nice to make the 2d physics system consistent with this 3d one
I was considering opening a new issue, but I think my problem is encapsulated here.
Another problem this setup presents is that PhysicalBone3D does not expose certain propertied or methods that exist in Rigidbody3D (for instance, apply_force() and center_of_mass are two that have come up).
'sleeping' is also missing as a property, though it must exist, because can_sleep exists.
It is odd that PhysicalBone3D does not extend Rigidbody3D to me, what is the reason for that?
It is odd that PhysicalBone3D does not extend Rigidbody3D to me, what is the reason for that?
See comments in https://github.com/godotengine/godot/pull/44150 and https://github.com/godotengine/godot/pull/58658 for rationale.
We can backport individual RigidBody3D properties to PhysicalBone3D as done in https://github.com/godotengine/godot/pull/82449.
In active ragdoll games, we will really have use cases for all the rigidbody3D properties and methods.
I am using apply_centra_impulse (force * delta) to approximate apply_central_force. But I also have a need for apply_central_torque, is_sleeping and get_colliding_bodies.
The biggest roadblock I have right now however is the lack of signals such as body_entered. Is there perhaps a simple workaround I'm missing for that?
edit - should I create a new issue for this?
edit - should I create a new issue for this?
Yes, as this proposal can't be implemented without breaking compatibility (while adding new methods/signals to PhysicalBone3D can be done).
I would like to see the following done...
Describe the project you are working on
Godot
Describe the problem or limitation you are having in your project
The current implementation of Physics3D Nodes:
Any use of
StaticBody3D
,AnimateableBody3D
,CharacterBody3D
,PhysicalBone3D
orRigidDynamicBody3D
was a Rigid Body on the Physics Server anyways, but these classes chose to only expose certain properties of that Rigid Body, which would often cause many new users to wonder if they were separate things, often causing issues when the user seeks to have a functionality from one in the other, not knowing they are indeed the same underlying object/type.Describe the feature / enhancement and how it helps to overcome the problem or limitation
The refactor of Physics3D Nodes:
sync_to_physics
: Moved toPhysicsObject3D
to support Syncing to Physics as a core feature of all Physics Objects.StaticBody3D
: This node was incredibly simple and can be recreated with aRigidBody3D
and setting BodyMode toSTATIC
.AnimateableBody3D
: With Sync to Physics being changed to a core feature of all Physics Objects, there is no longer a purpose for this node.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
The goal is the simplify the Physics Structure in Godot, and make it easy to teach and easier to understand.
Physics Objects we have for Godot:
Body
: Anything that has shapes that fills up space in the Physics World.Area
: Anything that has shapes that overlaps space in the Physics World.Body
can have two types:RigidBody
andSoftBody
RigidBody
can have four modes:STATIC
,KINEMATIC
,DYNAMIC
,DYNAMIC_LINEAR
- (LEGEND)- PVI = Physics Velocity Integration (Updates position with velocity) PFI = Physics Force Integration (Updates velocity with forces/user-code move) PS = Physics Simulation (Default Physics PVI/PFI Implementation)
STATIC
: No PVI,NoPFI, Optimized to not be movedKINEMATIC
: No PVI, PFI, Moved by user-codeDYNAMIC
: PVI, PFI, Moved by PS and user-codeDYNAMIC_LINEAR
: PVI, PFI, Moved by PS and user-code, rotation locked for use with CharactersWith this proposal all users will be covered by
RigidyBody3D
and creating user-derived types/scenes from it, to implement higher-level functionality while knowing theRigidBody3D
is a proper medium-level type and fully exposes the underlying low-level interface.If this enhancement will not be used often, can it be worked around with a few lines of script?
This a core structural/implementation change.
Is there a reason why this should be core and not an add-on in the asset library?
This a core structural/implementation change.