I’ve spent ages today trying to get a touch event to fire in a script, I tried the following:
Using the same syntax as ‘pointerdown’, which actually fires for pointer down:
document.addEventListener("touchstart", evt => {
console.log("touchstart");
this.touched();
});
Using some example I found in VideoPlayer.ts in the engine files:
window.addEventListener("touchstart", e => {
console.log("touchstart");
})
Neither of these seem to fire when testing on device or using WebXR AR simulator. Am I missing something really obvious?
Original Post on Discord
by user 103054507105067008
marcel
(marwi)
November 22, 2022, 12:00am
2
I just tried this little bit - works both in browser with touch simulation, on device and in WebAR (Android Pixel 4a):
export class MyScript extends Behaviour {
start() {
this.context.domElement.addEventListener("touchstart", e => {
console.log("touchstart", e);
for (let i = 0; i < e.changedTouches.length; i++) {
const touch = e.changedTouches[i];
const ray = this.context.mainCameraComponent!.screenPointToRay(touch.clientX, touch.clientY);
Gizmos.DrawRay(ray.origin, ray.direction, 0xff0000, 10);
}
});
}
}
I’m adding a little helper method to the camera in the next version, that’s the code for it:
private static _origin: THREE.Vector3 = new THREE.Vector3();
private static _direction: THREE.Vector3 = new THREE.Vector3();
public screenPointToRay(x: number, y: number, ray?: Ray): Ray {
const origin = Camera._origin;
origin.set(x, y, -1);
this.context.input.convertScreenspaceToRaycastSpace(origin);
origin.z = -1;
origin.unproject(this.cam);
const dir = Camera._direction.set(origin.x, origin.y, origin.z);
const camPosition = getWorldPosition(this.cam);
dir.sub(camPosition);
dir.normalize();
if (ray) {
ray.set(camPosition, dir);
return ray;
}
else {
return new Ray(camPosition.clone(), dir.clone());
}
}
marcel
(marwi)
November 22, 2022, 12:00am
3
So maybe something with the WebAR simulator?
Just tried and get errors about screenPointToRay
not existing on 2.47.2-pre
by user 103054507105067008
marcel
(marwi)
November 22, 2022, 12:00am
5
That’s what I wrote and why I sent you the method too
Ah I see, adding that
by user 103054507105067008
Do I add that to the source Camera ICamera script?
by user 103054507105067008
marcel
(marwi)
November 22, 2022, 12:00am
8
You can or you can just add it as a separate function to your component for testing and replace this.cam
with this.context.mainCamera
I’m having trouble migrating that second sample into my test script due to things like camera not having something called _origin
and other bits but if it’s landing in the next version I will give it a proper test for sure
by user 103054507105067008
marcel
(marwi)
November 22, 2022, 12:00am
10
Those are just static vector fields, see the code sample, you can replace them too or even get rid of them for testing and create new vectors
Got it down to this but Ray is not defined
private _origin: THREE.Vector3 = new THREE.Vector3(0,0,0);
private _direction: THREE.Vector3 = new THREE.Vector3();
public screenPointToRay(x: number, y: number, ray?: Ray): Ray {
const origin = this._origin;
origin.set(x, y, -1);
this.context.input.convertScreenspaceToRaycastSpace(origin);
origin.z = -1;
origin.unproject(this.context.mainCamera);
const dir = this._direction.set(origin.x, origin.y, origin.z);
const camPosition = getWorldPosition(this.context.mainCamera);
dir.sub(camPosition);
dir.normalize();
if (ray) {
ray.set(camPosition, dir);
return ray;
}
else {
return new Ray(camPosition.clone(), dir.clone());
}
}
by user 103054507105067008
marcel
(marwi)
November 22, 2022, 12:00am
13
import { Ray } from threejs
Rays from touches are now drawing! I am not doing a victory dance, thank you!
by user 103054507105067008
I think the reason why the touch events weren’t firing is the this.context.domElement.addEventListener()
bit rather than document.addEventListener()
, guessing that is a quirk of WebXR? Would be useful if that was documented somewhere as I wouldn’t have guess that
by user 103054507105067008
marcel
(marwi)
November 24, 2022, 12:00am
16
Btw @ROBYER1 latest release contains the method on the camera!
Thankyou!
by user 103054507105067008
@marcel I tried a load of things and still can’t get touch events to fire on iOS in Mozilla WebXR viewer, I documented what I did here, any thoughts on what else I can try?
opened 01:01PM - 25 Nov 22 UTC
closed 10:33PM - 09 Dec 22 UTC
fixed → to verify
### Describe the bug 💬
Using touch events subscribed at
```
this.conte… xt.domElement.addEventListener("touchstart", e => {
console.log("touchstart", e);
for (let i = 0; i < e.changedTouches.length; i++) {
const touch = e.changedTouches[i];
const ray = this.screenPointToRay(touch.clientX, touch.clientY);
Gizmos.DrawRay(ray.origin, ray.direction, 0xff0000, 10);
}
});
```
Those events don't seem to fire raycasts in AR on iOS in Mozilla WebXR Viewer (the touch events do fire outside of AR though on iOS), but it works fine on Android inside/outside AR using Chrome. You should be able to see the red debug rays drawn when performing touches while in AR and non AR view in the sample project
Related Discord forum post: https://discord.com/channels/717429793926283276/1044292640176345118/1044293702002163823
### Operating System 👩💻
iOS (mobile), Android (mobile)
### What browsers are you seeing the problem on? 🏄♂️
Chrome, Mozilla XR
### Editor Version 🎲
2022.x
### Needle Exporter version
2.49.0-pre
### Project Info (Unity only) 📜
```json
{
"ExportInfoGameObjectName": "Export Info",
"ExportInfoGameObjectIsEnabled": true,
"UnityProjectPath": "C:/Unity_Projects/NeedleWebDemos/Assets",
"UnityVersion": "2022.1.23f1",
"SceneName": "ARDemo",
"ProjectPath": "Projects/ARDemo",
"ProjectDirectoryExists": true,
"ProjectIsInstalled": true,
"NeedleEngineInstalled": true,
"HasNodeInstalled": true,
"HasTokTxInstalled": true,
"HasMinimumToktxVersionInstalled": false,
"RenderPipeline": "UniversalRenderPipelineAsset (UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset)",
"GzipEnabled": false,
"NeedleEngineExporterVersion": "2.49.0-pre",
"NeedleEngineVersion": "2.49.0-pre",
"NeedleEngineExporterPath": "Packages/com.needle.engine-exporter/package.json",
"NeedleEnginePath": "Packages/com.needle.engine/package.json",
"FileStats": "By Type:\r\n•\t.glb → x 2 = 0.7 mb\r\n•\t<b>Total = 0.7 mb</b>\r\n----\r\nBy Directory:\r\n•\tassets → x 2 = 0.7 mb\r\n",
"NeedleComponentsInScene": [
"Needle.Engine.ExportInfo",
"Needle.Engine.Codegen.ComponentGenerator",
"Needle.Engine.Components.GltfObject",
"Needle.Engine.Components.WebARSessionRoot",
"Needle.Engine.Components.TeleportTarget",
"Needle.Engine.Components.ObjectRaycaster",
"Needle.Engine.AdditionalData.LightShadowData",
"Needle.Engine.Components.WebXR",
"Needle.Engine.Components.WebXRSync",
"Needle.Engine.Components.OrbitControls",
"Needle.Engine.AdditionalData.CameraARData",
"Needle.Typescript.GeneratedComponents.AlignHeightToGround",
"Needle.Typescript.GeneratedComponents.ARControls",
"Needle.Typescript.GeneratedComponents.DragControlsEPM"
],
"TypeCacheIsDirty": false,
"TypeScriptTypes": []
}
```
### Steps to reproduce 🔢
```bash
1. Open Repro project in Unity 2022.1.23f1
2. Run local server, open on iOS in Mozilla WebXR viewer
3. Try touching the screen outside of AR mode to see raycasts working, then try entering AR mode and touching to raycast
4. Do the same on Android with Chrome to see AR raycasts work fine
```
### Reproduction ♻
Repro Project:
[ARDemo-221125_uw.zip](https://github.com/needle-tools/needle-engine-support/files/10092771/ARDemo-221125_uw.zip)
### Validations 🩹
- [X] Follow our [Code of Conduct](https://github.com/needle-tools/needle-engine-support/blob/main/CODE_OF_CONDUCT.md)
- [X] Read the [docs](https://docs.needle.tools).
- [X] Check that there isn't [already an issue](https://github.com/needle-tools/needle-engine-support/issues) that reports the same bug to avoid creating a duplicate.
- [X] Make sure this is a Needle-Engine-specific issue. For example if it's a Unity related bug, it should be reported to [Unity](https://unity3d.com/unity/qa/bug-reporting) instead.
- [X] Check that this is a concrete bug. For Q&A open a [GitHub Discussion](https://github.com/needle-tools/needle-engine-support/discussions) or join our [Discord Chat Server](https://discord.needle.tools).
- [X] The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.
by user 103054507105067008
Made a new repro, works good on Chrome Android but on iOS Mozilla WebXR no touch events fire in AR. touchstart
is subscribed to through this.context.domElement, document and window in all three places just in case and I also use WebXREvent.XRStarted to refresh those event listeners https://rectangular-noble-dentist.glitch.me/
by user 103054507105067008
I got touch events registering on iOS WebXR AR using window.addEventListener
, however there is an error with screenPointToRay which is THREE.BufferGeometry.computeBoundingSphere():
https://github.com/needle-tools/needle-engine-support/issues/118#issuecomment-1330869123
by user 103054507105067008