From 6a45e3b391bfb130f6b99605409dc618f15db4bf Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Mon, 6 Jan 2025 17:59:08 +0000 Subject: [PATCH] The Arcade Physics `Body.setGameObject` and `StaticBody.setGameObject` methods have been updated to do the following: Return if no valid Game Object is passed. Disable and null the body of the existing Game Object if the Body has one. Set the `body` property, even if it doesn't exist (converts non-physics objects into physics objects). Calls `setSize` to update the body dimensions to make the new Game Object and finally sets `enable` based on the given parameter, which is now correctly referenced. The StaticBody version also has a new parameter, `enable` which matches that of the Dynamic Body and defaults to `true` (the original state). Fix #6969 --- src/physics/arcade/Body.js | 27 +++++++++++++------- src/physics/arcade/StaticBody.js | 43 ++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js index 268dda5cf4..fbc86a8a77 100644 --- a/src/physics/arcade/Body.js +++ b/src/physics/arcade/Body.js @@ -1414,12 +1414,12 @@ var Body = new Class({ * * If this body already has a Game Object, then it will remove itself from that Game Object first. * - * Only if the given `gameObject` has a `body` property will this Body be assigned to it. + * If the given `gameObject` doesn't have a `body` property, it is created and this Body is assigned to it. * * @method Phaser.Physics.Arcade.Body#setGameObject * @since 3.60.0 * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Body belongs to. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to assign this Body to. * @param {boolean} [enable=true] - Automatically enable this Body for physics. * * @return {Phaser.Physics.Arcade.Body} This Body object. @@ -1428,25 +1428,34 @@ var Body = new Class({ { if (enable === undefined) { enable = true; } - // Remove from the World - this.world.remove(this); + if (!gameObject || !gameObject.hasTransformComponent) + { + // We need a valid Game Object to continue + return this; + } + + var world = this.world; if (this.gameObject && this.gameObject.body) { + world.disable(this.gameObject); + // Disconnect the current Game Object this.gameObject.body = null; } - this.gameObject = gameObject; - if (gameObject.body) { - gameObject.body = this; + // Remove the body from the world, but don't disable the Game Object + world.disable(gameObject); } - this.setSize(); + this.gameObject = gameObject; - this.world.add(this); + gameObject.body = this; + + // This will remove the body from the tree, if it's in there and add the new one in + this.setSize(); this.enable = enable; diff --git a/src/physics/arcade/StaticBody.js b/src/physics/arcade/StaticBody.js index bc7cb7c8ca..b7c687c2b7 100644 --- a/src/physics/arcade/StaticBody.js +++ b/src/physics/arcade/StaticBody.js @@ -507,37 +507,64 @@ var StaticBody = new Class({ /** * Changes the Game Object this Body is bound to. + * * First it removes its reference from the old Game Object, then sets the new one. + * + * This body will be resized to match the frame dimensions of the given Game Object, if it has a texture frame. * You can optionally update the position and dimensions of this Body to reflect that of the new Game Object. * * @method Phaser.Physics.Arcade.StaticBody#setGameObject * @since 3.1.0 * - * @param {Phaser.GameObjects.GameObject} gameObject - The new Game Object that will own this Body. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to assign this Body to. * @param {boolean} [update=true] - Reposition and resize this Body to match the new Game Object? + * @param {boolean} [enable=true] - Automatically enable this Body for physics. * * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. * * @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject */ - setGameObject: function (gameObject, update) + setGameObject: function (gameObject, update, enable) { - if (gameObject && gameObject !== this.gameObject) + if (update === undefined) { update = true; } + if (enable === undefined) { enable = true; } + + if (!gameObject || !gameObject.hasTransformComponent) { - // Remove this body from the old game object - this.gameObject.body = null; + // We need a valid Game Object to continue + return this; + } - gameObject.body = this; + var world = this.world; - // Update our reference - this.gameObject = gameObject; + if (this.gameObject && this.gameObject.body) + { + world.disable(this.gameObject); + + // Disconnect the current Game Object + this.gameObject.body = null; } + if (gameObject.body) + { + // Remove the body from the world, but don't disable the Game Object + world.disable(gameObject); + } + + this.gameObject = gameObject; + + gameObject.body = this; + + // This will remove the body from the tree, if it's in there and add the new one in + this.setSize(); + if (update) { this.updateFromGameObject(); } + this.enable = enable; + return this; },