Hello, sorry if I ask an already responded question.
I’m working on a 2D project.
I’m trying to create a point and click feature on a map, so I’m using the Ray Cast and bounding box solution :
Player.prototype.doRayCast = function (screenPosition) {
// Initialise the ray and work out the direction of the ray from the a screen position
this.cameraEntity.camera.screenToWorld(screenPosition.x, screenPosition.y, this.cameraEntity.camera.nearClip, Player.ray.origin);
this.cameraEntity.camera.screenToWorld(screenPosition.x, screenPosition.y, this.cameraEntity.camera.farClip, Player.ray.direction);
Player.ray.direction.sub(Player.ray.origin).normalize();
// Test the ray against the ground
var result = this.groundShape.intersectsRay(Player.ray, Player.hitPosition);
if (result) {
this.movePlayer(Player.hitPosition.x, Player.hitPosition.y, Player.hitPosition.z);
}
This was working fine. Now I want to fix the ratio of my screen view so the view is always 16:9.
So I set the Fill Mode to “Fixed Ratio” in setting.
I think I understand the reason, the camera added some “cinema box” around to keep the ratio, and it’s making my click detection point at the wrong place.
But I’m not sure on how to fix that.
Is someone have an idea ?
This is most likely happening because the mouse click event is reporting the window coordinates. Those are starting from the top/left pixel of the window, not the rendered canvas.
You will need to accommodate for that and pass the canvas click coordinates to your raycast method.
Hello, thank you, so this is the fix I came with :
Player.prototype.isHorizontalCinemaBox = function () {
let unitY = window.innerWidth / 16;
let unitX = window.innerHeight / 9;
let result = 0;
if (unitX > unitY) {
//we have horizontal cinema box
let canvasSizeHeight = unitY * 9;
result = (window.innerHeight - canvasSizeHeight) / 2;
}
return result;
};
Player.prototype.isLateralCinemaBox = function () {
let unitY = window.innerWidth / 16;
let unitX = window.innerHeight / 9;
let result = 0;
if (unitX < unitY) {
//we have lateral cinema box
let canvasSizeWidth = unitX * 16;
result = (window.innerWidth - canvasSizeWidth) / 2;
}
return result;
};
Player.prototype.doRayCast = function (screenPosition) {
// Initialise the ray and work out the direction of the ray from the a screen position
let offsetX = this.isLateralCinemaBox();
let offsetY = this.isHorizontalCinemaBox();
this.cameraEntity.camera.screenToWorld(screenPosition.x - offsetX, screenPosition.y - offsetY, this.cameraEntity.camera.nearClip, Player.ray.origin);
this.cameraEntity.camera.screenToWorld(screenPosition.x - offsetX, screenPosition.y - offsetY, this.cameraEntity.camera.farClip, Player.ray.direction);
Player.ray.direction.sub(Player.ray.origin).normalize();
// Test the ray against the ground
var result = this.groundShape.intersectsRay(Player.ray, Player.hitPosition);
if (result) {
// this.app.fire('getPosition', this.player.getPosition(), Player.hitPosition);
this.movePlayer(Player.hitPosition.x, Player.hitPosition.y, Player.hitPosition.z);
}
};
I had an idea when writing it, maybe you can create a new variation of ScreenToWorld which do that natively ? Whatever, I let it here so people can use it as they want.
bye !
edit : I can’t find how to put the subject on “Solved” sorry