From 4284de1b7663622b2516d7118611b4ed43857025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Vivet?= Date: Wed, 13 May 2026 23:10:53 +0200 Subject: [PATCH 1/2] Make in-game editor gizmo move objects without delay --- GDJS/Runtime/InGameEditor/InGameEditor.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/GDJS/Runtime/InGameEditor/InGameEditor.tsx b/GDJS/Runtime/InGameEditor/InGameEditor.tsx index 72738b1b9016..20a96a52709d 100644 --- a/GDJS/Runtime/InGameEditor/InGameEditor.tsx +++ b/GDJS/Runtime/InGameEditor/InGameEditor.tsx @@ -626,7 +626,7 @@ namespace gdjs { class ObjectMover { private editor: InGameEditor; private _changeHappened = false; - private startTime = 0; + private _isMoving = false; constructor(editor: InGameEditor) { this.editor = editor; @@ -648,15 +648,17 @@ namespace gdjs { > = new Map(); startMove() { + if (this._isMoving) return; + this._isMoving = true; this._changeHappened = false; this._objectInitialPositions.clear(); - this.startTime = Date.now(); } endMove(): boolean { const changeHappened = this._changeHappened; this._objectInitialPositions.clear(); this._changeHappened = false; + this._isMoving = false; return changeHappened; } @@ -674,10 +676,6 @@ namespace gdjs { scaleZ: float; } ) { - if (Date.now() - this.startTime < 150) { - // Avoid miss-clicks gizmo dragging point to change object positions. - return; - } selectedObjects.forEach((object) => { if (this.editor.isInstanceLocked(object)) { return; @@ -2403,6 +2401,15 @@ namespace gdjs { !dummyThreeObject.position.equals(initialDummyPosition) || !dummyThreeObject.rotation.equals(initialDummyRotation) || !dummyThreeObject.scale.equals(initialDummyScale); + + // Apply the movement to the selected objects right away, + // in the same tick as the gizmo update, so the object + // follows the gizmo without any visible delay. + this._objectMover.startMove(); + this._objectMover.move( + this._selection.getSelectedObjects(), + this._selectionControlsMovementTotalDelta + ); }); this._selectionControls = { From 18d50c29e17b1b8bc0a3eebc0446cb25d101a54d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Vivet?= Date: Thu, 14 May 2026 12:30:15 +0200 Subject: [PATCH 2/2] prevent miss click if not clicked and not moved --- GDJS/Runtime/InGameEditor/InGameEditor.tsx | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/GDJS/Runtime/InGameEditor/InGameEditor.tsx b/GDJS/Runtime/InGameEditor/InGameEditor.tsx index 20a96a52709d..b160bb4a5091 100644 --- a/GDJS/Runtime/InGameEditor/InGameEditor.tsx +++ b/GDJS/Runtime/InGameEditor/InGameEditor.tsx @@ -2274,9 +2274,13 @@ namespace gdjs { const initialDummyPosition = new THREE.Vector3(); const initialDummyRotation = new THREE.Euler(); const initialDummyScale = new THREE.Vector3(); + let xyzClickCursorX: float | null = null; + let xyzClickCursorY: float | null = null; threeTransformControls.addEventListener('change', (e) => { if (!threeTransformControls.dragging) { this._selectionControlsMovementTotalDelta = null; + xyzClickCursorX = null; + xyzClickCursorY = null; this._updateDummyLocation( dummyThreeObject, @@ -2296,6 +2300,27 @@ namespace gdjs { return; } + // Avoid moving the object on an XYZ-handle click without drag. + if ( + this._transformControlsMode === 'translate' && + threeTransformControls.axis === 'XYZ' + ) { + const inputManager = this._runtimeGame.getInputManager(); + const cursorX = inputManager.getCursorX(); + const cursorY = inputManager.getCursorY(); + if (xyzClickCursorX === null) { + xyzClickCursorX = cursorX; + xyzClickCursorY = cursorY; + } + if ( + cursorX === xyzClickCursorX && + cursorY === xyzClickCursorY + ) { + initialDummyPosition.copy(dummyThreeObject.position); + return; + } + } + let translationX = dummyThreeObject.position.x - initialDummyPosition.x; let translationY =