fenomas / noa

Experimental voxel game engine.
MIT License
608 stars 86 forks source link

raycast using touch event page x/y instead of camera position #167

Closed itzTheMeow closed 2 years ago

itzTheMeow commented 2 years ago

I want to add mobile controls to my game, however the crosshair is a little difficult to play with. I want to implement the ability to touch a block and place something on top of it, instead of using the position of the camera crosshair. I noticed this function: image and i want to know how to adapt it to be able to use a touch event x and y to get the block you click on.

itzTheMeow commented 2 years ago

i think it would have something to do with camera._localGetTargetPosition, however the function isn't documented

MCArth commented 2 years ago

Hi, take a look at docs/positions.md, it explains the global/local position co-ordinate system. You can then use some babylon methods to get the pick point and vector you want :)

fenomas commented 2 years ago

@itzTheMeow Hi, there's no specific API for this at the moment, but here is how to do it:

function pickBlockFromScreenCoords(x, y, dist = 10, testFn = null) {
    var ray = noa.rendering.getScene().createPickingRay(x, y)
    var pos = [ray.origin.x, ray.origin.y, ray.origin.z]
    var dir = [ray.direction.x, ray.direction.y, ray.direction.z]
    return noa._localPick(pos, dir, dist, testFn)
}

Note that it's using createPickingRay, which is a Babylon scene API, so the x, y values will need to be whatever Babylon expects them to be. I'm not sure offhand if they're relative to the screen or to the canvas element.

The dist param is the max raycast distance, and testFn should be a function that returns true for block IDs that the raycast "hits". If you omit the test function it defaults to testing for solid blocks.

itzTheMeow commented 2 years ago

I'm not sure offhand if they're relative to the screen or to the canvas element.

both would be the same size anyway

but thanks ill try it out

fenomas commented 2 years ago

Hi, assuming this worked okay, but let me know if not.