Reset AR Scaling

Hey Guys,

im currently a bit stuck at the following problem:

i want to provide my user a possibility to reset the ar spawned object back to “normal” or original size. For that i have a 2d html button which is only visible in ar which i preserve with the following click eventlistener:

start(): void {
        // Get the element from the DOM
        this.btnElement = document.querySelector(this.htmlBtnSelector) as 
HTMLButtonElement;
        this.percentageElement = document.querySelector(this.htmlPercentageSelector) as HTMLParagraphElement;
        
        if (this.btnElement) {
            this.btnElement.addEventListener('click',  this.onClick);
        } 
    }

    private onClick = () => {
        if(this.xrRig){
            // Reset the scale safely
            this.xrRig.scale.set(1,1,1);
            this.xrRig.updateMatrix();
            this.xrRig.updateMatrixWorld(true);  // Force update of world matrix
        } else {
            console.error("missing xrRig")
        }
    }

in the “percentageSelector” html element i display the current scaled percentage like this:

    onUpdateXR(args: NeedleXREventArgs): void {
        this.content = Math.round((1 / args.xr.rigScale) * 20) * 5 + '%';
        this.percentageElement!.innerHTML = this.content;

        if(!this.xrRig)
            this.xrRig = args.xr.rig?.gameObject;
    }

but when i click on my button in ar, the object currently displayed behaves not as expected.

Expected: it stays where it is and scales back to 100%

what happens: it moves in position (random in x,y,z) and is nearly uncontrollable afterwards.

what am i missing here? please halp <3

Hello! The issue you’re facing with the xrRig moving unexpectedly after resetting its scale might be due to how transformation matrices are being updated.

When you set the scale back to (1, 1, 1), it’s important to ensure that the position and other transformations are also being handled correctly to avoid changes in the object’s position.

To fix this, try applying the following modifications:

  1. Update Position After Resetting Scale: Before resetting the scale of the xrRig, store its current position and then reapply it after resetting the scale.

  2. Ensure the Input System is Not Affecting the Transformations: If any kind of input events are applied to the XR rig simultaneously, they might cause unexpected behavior.

Here’s an updated version of your onClick method:

private onClick = () => {
    if (this.xrRig) {
        // Store current position
        const currentPosition = this.xrRig.position.clone();

        // Reset the scale safely
        this.xrRig.scale.set(1, 1, 1);
        this.xrRig.updateMatrix();
        this.xrRig.updateMatrixWorld(true);  // Force update of world matrix

        // Reapply the original position
        this.xrRig.position.copy(currentPosition);
        this.xrRig.updateMatrix(); // Update the matrix again after position change
    } else {
        console.error("missing xrRig");
    }
}

Key Changes:

  • The current position of the xrRig is stored and then reapplied after resetting the scale to keep the object in place.
  • Make sure the input events and transformations are not interfering during this reset process.

If you still experience issues, please share any additional details or logs that could provide more insights into the problem.

1 replies left - Get a PRO license for more AI replies.
thread_tFWStDprMzO1RlkJnB4O71lE
Reply to this message to continue the conversation

Hi,

This is on Android? What is this.xrRig in your code?

It is the Rig in the active NeedleXRSession

basically just:

onUpdateXR(args: NeedleXREventArgs): void {
        this.content = Math.round((1 / args.xr.rigScale) * 20) * 5 + '%';
        this.percentageElement!.innerHTML = this.content;

        if(!this.xrRig)
            this.xrRig = args.xr.rig?.gameObject;
    }

Could you send a bugreport that reproduces your issue? Would help in debugging this. Thank you! (You can use the menu item “Needle Engine/Report a bug” in Unity)

The Bugreport is uploaded :smiley:

Thank you

Okay so i now tried various ways of scaling the WebXRRig back to 100% while in AR.

Since the Userinput (Pinch) in AR does not Scale the displayed GameObject but the User itself i used similar code to what it written in “WebARSessionRoot.ts”.

i tired

const rigObject = NeedleXRSession.active?.rig?.gameObject;
        if(rigObject){
            rigObject.scale.x = 1
            rigObject.scale.y = 1
            rigObject.scale.z = 1
            rigObject.updateMatrix()
        }

and

const rigObject = NeedleXRSession.active?.rig?.gameObject;
        if(rigObject){
           const v3 = new Vector3(1,1,1)
            setWorldScale(rigObject, v3)
        }

or all things around this

const rigObject = NeedleXRSession.active?.rig?.gameObject;
        if(rigObject){
           rigObject.scale.set(1,1,1)
           //or
           rigObject.scale.setScalar(1)
        }

it all ends in the same scenario. the user get scaled but not in the right way. the user object appears way smaller than at start of the session. the objects seems to not be on the floot and floats further away aswell as higher.

Im pretty desperate right now, since im trying this now for 7 to 9 hours straight in a row and nothing seems to work…

maybe someone has a nice shot to try or a already finished solution…

Thanks <3

Hi, we’ll be looking into it.

Hi,

you can add this codensippet to a component for example.

The scale here is the same as “arScale” in the WebXR component - meaning larger values make your scene appear smaller. SO to reset the scale to whatever you had at the beginning you can set it to the same value as in Unity’s WebXR component.

    private setARScale(scale: number) {
        if (this.context.xr?.rig?.gameObject) {
            const rig = this.context.xr.rig.gameObject;
            const currentScale = NeedleXRSession.active?.rigScale || 1;
            let newScale = (1 / scale) * currentScale;
            const scaleMatrix = new Matrix4().makeScale(newScale, newScale, newScale).invert();
            rig.matrix.premultiply(scaleMatrix);
            rig.matrix.decompose(rig.position, rig.quaternion, rig.scale);
        }
    }

This might become easier in the next update and allow you to simply set arScale on the current WebARSessionRoot to archieve the same.

Lovely,
thank you <3 it works as intended

1 Like