screenToWorld after changing screen size at runtime

Hi!
I have two nodes on my screen. One is UI object and one is 3D world object
Camera is in Ortho mode
I want to move 3d world object to UI object position on click
I can do this by using camera.screenToWorld. It works fine until I want to switch screen size/resolution. Then my 3d node moves incorrect
Снимок экрана 2022-07-10 174601

But everything works fine if I change design width/height in project settings to whatever values
I think the problem is changing size at runtime

I tested it with this demo and it works fine.

Hi!
In that reference box was moving by mouse touch position
But I’m getting incorrect position trying to follow position of other node

I added richtext “PlaceHere” as targer position node for the box

@ccclass(‘ScreenToWorldPoint’)

export class ScreenToWorldPoint extends Component {

@property(Node)

box !: Node;

@property(Label)

distanceLabel !: Label;

@property(Camera)

Camera3D !: Camera;

@property(Node)

target !: Node

_distance = 0;

start () {

    var canvas = find('Canvas')!;

    canvas.on(Node.EventType.TOUCH_START, this.onTouchStart, this);

    canvas.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);

    this._distance = 0.5;

}

onTouchStart(evt: EventTouch) {

    this.moveBox(evt.getLocation());

}

onTouchMove(evt: EventTouch) {

    this.moveBox(evt.getLocation());

}

moveBox (touchPos: Vec2) {

    const targetPosition = this.target.worldPosition

    let pos = this.Camera3D.screenToWorld(new Vec3(targetPosition.x, targetPosition.y, this._distance));

    this.box.position = this.box.parent!.getComponent(UITransform)!.convertToNodeSpaceAR(pos);

}

onDistanceChanged(slider: Slider) {

    this._distance = parseFloat(slider.progress.toFixed(2));

    this.distanceLabel.string = 'distance : ' + this._distance;

}

}

But it does look correct to me if I rotate screen to 90 degrees

The question is why does screenToWorld works like this? What should I do to get box position change correctly with any screen resolution in debug mode?

My guess it’s somehow related to design width and design height (which is 960x640 in this example)


You can choose to listen to either of these two events to perform a position reset.

Yeah but I don’t get it
screenToWorld gives me incorrect values everytime I’m not using my design height and design width
You can see this on my second picture. Screen is 960x640 which is my design height and design width. Box was placed to richtext position using values from screenToWorld.

But if I change it runtime to any other resolution then screenToWorld will give me incorrect position

@ccclass(‘ScreenToWorldPoint’)

export class ScreenToWorldPoint extends Component {

@property(Node)

box !: Node;

@property(Camera)

Camera3D !: Camera;

@property(Node)

target !: Node

start () {

    View.instance.on('canvas-resize', this.onSizeChanged, this)

}

onSizeChanged(): void {

    const targetPosition = this.target.worldPosition

    let pos = this.Camera3D.screenToWorld(new Vec3(targetPosition.x, targetPosition.y, 0.5));

    this.box.position = this.box.parent!.getComponent(UITransform)!.convertToNodeSpaceAR(pos);

}

}

Sorry, I misunderstood it.I thought you wanted the label to keep following the cube node.
This is because the 3d camera display window has been modified, but the worldPosition of the nodes are still the same.The calculations for 2d and 3d cameras differ.

Okay
I have no clue then
Can you provide a working solution for my case please?

Creator3.5.0_3D_ModelText.zip (3.7 MB)
like this?

In this example UI node following 3D node
I want to do the opposite - moving 3d node to UI node position

Then you should be touching the label node to move the cube node to follow the label, see the code now is touch to move the cube?
do you just want the cube node and label node to be in the same position after the resolution change? If so, the cube’s worldPosition will change. Is that you want?

I want that when I’m clicking on a 3d object, it moves to the position of the label
Everything works fine until the screen resolution changes.


NewProject_112.zip (1.6 MB)

Okay we figured this out

import { view } from “cc”;

let scaleX = view.getScaleX()
let scaleY = view.getScaleY()
let posNode = your UI node world position
let z = distance to camera (we are using 0.5 because of ortho mode)
let pos = camera.screenToWorld(new Vec3(posNode .x * scaleX, posNode .y * scaleY, z))