GDevelop
GDevelop copied to clipboard
Change physics actions to apply forces at center of mass by default
Description
The first time I tried using physics, my objects were always spinning. It was frustrating and confusing until I realized that I left the "apply force at" fields blank and they need to use the center point (or center of mass). I think this problem affects many new users, and it adds two extra steps when nearly all users want the force to be applied at the center.
Solution suggested
- [ ] When the "apply force to" fields are blank, they should use the center of mass of the object.
Alternatives considered
This could affect existing games that rely on the force being applied to the origin. This change might require a new version of the action to be created to maintain the same behavior.
I'm going to see if I can make this change. Here is my idea:
4ian/GDevelop/Extensions/Physics2Behavior/physics2runtimebehavior.ts
applyForce(
forceX: float,
forceY: float,
positionX: float,
positionY: float
): void {
// If there is no body, set a new one
if (this._body === null) {
if (!this.createBody()) return;
}
const body = this._body!;
// Wake up the object
body.SetAwake(true);
// Use the center of mass if no position is provided
if (positionX === null) {
positionX = this.getMassCenterX()
}
if (positionY === null) {
positionY = this.getMassCenterY()
}
// Apply the force
body.ApplyForce(
this.b2Vec2(forceX, forceY),
this.b2Vec2Sec(
positionX * this._sharedData.invScaleX,
positionY * this._sharedData.invScaleY
),
// TODO Should let Box2d awake the object itself.
false
);
}
This is more or less how you would do it for a traditional JS function (but with undefined to allow the caller to not pass anything, or using null as you did but then the caller needs to pass null).
The issue is that expressions returning numbers in GDevelop are always returning "0" if you don't specify anything. They are guaranteed to be a number. So this approach would need to support a new construction in an action/condition, which would be numbers which, when not filled, are sending null or undefined to the JavaScript. This would also need to change slightly in the interface to make clear to the user that "it's fine not to fill this, in which case the center of mass will be used". In other words, it's a concept of "optional" parameters.
@4ian thanks for the detailed response. I'm afraid the scope of the change you described is outside my current abilities.
I'll leave this for someone else to take the lead.
The issue is that expressions returning numbers in GDevelop are always returning "0" if you don't specify anything. They are guaranteed to be a number. So this approach would need to support a new construction in an action/condition, which would be numbers which, when not filled, are sending null or undefined to the JavaScript. This would also need to change slightly in the interface to make clear to the user that "it's fine not to fill this, in which case the center of mass will be used". In other words, it's a concept of "optional" parameters.
Are there any examples of similar functionality in GDevelop that I can learn from?
My javascript skills have increased enough to attempt this again.
Is this being done anywhere else in the GDevelop app?
I believe this is one of the biggest obstacles when people try using Physics for the first time.
Box2D has 2 methods:
- one for a force at the center
- one for a force at a given location https://box2d.org/documentation/classb2_body.html#a942be8e1cd2bcd06f53c4638c45a9525
I think it would make sense to have 2 actions in GDevelop too.