Potato Logo Half Baked City Potato Logo

User Inputs Part 1 – Touch Screens

This tutorial series will teach us how to listen for user input via:

  1. Touch Screens
  2. Keyboards
  3. VR Controllers

By the end of this tutorial series, we'll end up with a WebXR app demoing input detection by controlling a spaceship

Step 1

We'll use the finished code from the glTF Assets Tutorial as our starting point

Let's begin by creating a new file /scripts/core/InputHandler.js for handling all user input. I personally like polling for controller inputs, so let's keep that in mind when filling it out

Detecting whether a mobile screen is touched or not is quite simple so we'll start with that. All we need is a boolean _screenTouched that keeps track of when the user has touched the screen. We can use the touchstart and touchend events to set it accordingly. Here's what we should end up

Now let's create an instance of it in Main.js underneath where we instantiate our SessionHandler. And instead of creating those handlers in the constructor let's move them into a seperate function called _createHandlers() that looks like this

Notice how we expose the Input Handler via global

Cool, let's make something happen now when the screen is touched to verify things are working properly. Since we have a planet and spaceship in front of us, let's make the spaceship fly towards the planet. Copy our code from /scripts/components/GLTFAsset.js to make /scripts/components/Spaceship.js as a start

We'll need to add a speed parameter to Spaceship.js and an update function that moves the Spaceship forward whenever the screen is touched. Here's what we get after those additions

I use the following convention: forward = negative Z direction

Now we just need to import Spaceship into Main.js and use that when instantiating the spaceship. We'll also need to change it's scope using this._spaceship = new Spaceship(... so that we can call its update(timeDelta) function from the update function in Main.js

Running it on our phones we see that the spaceship does move, but not in the intended direction. Rather than reorient the asset in code itself, let's open up a 3D modeling tool like Blender to rotate the asset 90° (if you don't want to venture into the realm of 3D modeling tools just yet, feel free to download the correctly oriented asset here)

To fix this we could have also just made forward the positive X direction, but then if we ever replaced this model with another that was oriented differently we'd get the same problem. There is an argument for using the positive Z direction so we could make use of Object3D's lookAt() function, but we'll find out in part 3 of this tutorial series that negative Z is best for WebXR

After updating our glb file with the correctly oriented asset, we just need to update the initial rotation of our Spaceship along the y-axis so that it's facing the planet once more. Now the spaceship moves in the correct direction, nice job!

Step 2

There's a little bug in our program, can you find it? Right now if we touch our screen before hitting the start button the ship still moves. We probably don't want that behavior so we have two options

  1. In Spaceship.js, check to see if a session is active before moving the spaceship
  2. In InputHandler.js, have isScreenTouched() return false if a session is not active

Either option will work, but I don't like the idea of Input Handler being dependent on Session Handler so we'll go with the first option

To do this, open up SessionHandler.js and

  1. Declare global.sessionActive = false; in the constructor
  2. Set global.sessionActive to true or false in the lock, unlock, and touchend events
  3. Add sessionstart and sessionend event listeners to renderer.xr to update global.sessionActive accordingly

SessionHandler.js should now contain something like this

Now we just check if global.sessionActive is true in the update function of Spaceship.js and everything works as it should!

I hope you're as excited to stop caring about mobile users for a while like I am, because this is hopefully the last tutorial dedicated to them for a long while

Finished code in action

Git Repository

Feeling generous/want to support me in writing tutorials? Then buy me a coffee, which I'll probably use for boba or almonds (raw and unsalted you heathens) because I don't like coffee

Continue on to Part 2 – Keyboards


Please Wait...

Log in/Sign up to comment

Server error, please try again later