I have a scene with a cube that can be dragged by a user.
After 10 seconds of dragging, we disable dragging by deactivating the DragControls component.
Till here it’s fine.
But when multiple users are in the scene and SyncTransform exists on the block, some information goes missing for the new users (i.e. original creation time of the block)
Hence, the block can still be moved, even though it was supposed to be immovable.
We want the creation time to persist and not be lost, for existing and even for new users to the room.
Next:
Do you have custom drag logic or are you using the built-in DragControls?
Would you like help integrating this with your block object’s existing components?
1 replies left - Get a PRO license for more AI replies. thread_qxLk3cmBGVMU4LvOKm7qelNo Reply to this post directly if you need further help (bottom right button)
Here’s also a copy of the code that I’ve written. Put this component to your scripts and attach it to the same object as your DragControls.
import { Behaviour, DragControls, Gizmos, serializable, syncField, } from '@needle-tools/engine';
export class SyncedInputChecker extends Behaviour {
/** The time after which the object is locked */
@serializable()
lockDelay: number = 10;
/** The time after which the object is automatically freed. This is additive to the lockDelay. If this number is 0 or below the input will never be automatically freed */
@serializable()
autoResetDelay: number = 20;
@serializable()
showDebug: boolean = true;
/**
* This field is networked and updated by this script when the user starts to click the object this component is attached to. The value is then sent to all connected remote users
*/
@syncField()
private pointerDownTime: number = 0;
get isLocked() {
// after 10 seconds no input is allowed anymore
return (
this.pointerDownTime <= 0 ||
Date.now() - this.pointerDownTime < this.lockDelay * 1000
);
}
// We expose an API to reset the state
resetState() {
this.pointerDownTime = 0;
}
// We use onPointerDown which happens when the user pressed the mouse button or touches the object or uses a spatial controller (VR)
onPointerDown() {
if (this.pointerDownTime > 0) return;
this.pointerDownTime = Date.now();
}
update() {
// a reference to this componnt could be stored once in onEnable or start
const dragcontrols = this.gameObject.getComponent(DragControls);
if (dragcontrols) dragcontrols.enabled = this.isLocked;
if (this.pointerDownTime > 0) {
let time = (Date.now() - this.pointerDownTime) / 1000;
// for testing we reset automatically
if (
this.autoResetDelay > 0 &&
time > this.lockDelay + this.autoResetDelay
) {
this.resetState();
}
// just visualizing the time here by drawing a label gizmo above our object - this can be removed for production or put behind a debug flag
if (this.showDebug && time > 0) {
const pos = this.gameObject.worldPosition;
pos.y += 1;
Gizmos.DrawLabel(
pos,
time.toFixed(0) + `${this.isLocked ? '' : ' (locked)'}`,
0.1,
undefined,
undefined,
this.isLocked ? 0x99ffdd : 0xff5500
);
}
}
}
}
Nope, just click the link. On mobile it can take a little moment to get ready. If unclear check the stackblitz terminal or try it locally (you can download the whole project as well if you want) or just use it as a reference