Day 61 of 100 Days of VR: Intro to Daydream Controller API and Swiping





0/5 (0 vote)
Introduction to Daydream Controller API and Swiping
Introduction
We set up the Google Daydream controller in the last post, today, we’re going to start looking at the APIs that are given to us that allow us to interact with the game model.
Specifically, the goal today is to learn how we can use these actions:
- Touchpad button press
- App button press
- Touchpad swiping actions
Interacting with the Daydream API
The first thing we need to do is set up a script that allows us to use the APIs
- In the game hierarchy, select
Player
(right now, it doesn’t really matter which) and create a new Script. Let’s call itPlayerInput
In the script, we’re going to see how can detect and use the inputs that we received from above like we discussed earlier.
Basic Button Press Detection Script
using UnityEngine;
public class PlayerInput : MonoBehaviour
{
// Update is called once per frame
void Update ()
{
if (GvrControllerInput.AppButtonDown)
{
print("Click App button down");
}
if (GvrControllerInput.ClickButtonDown)
{
print("Click Touchpad");
}
if (GvrControllerInput.IsTouching)
{
print("Position Vector: " + GvrControllerInput.TouchPos);
}
}
}
Walking Through the Code
Hopefully, at this point, there isn’t anything mind-blowing about the code that we’re seeing right here. If we were to run the code and play the game with our emulator:
- Shift + Left Click will trigger
GvrControllerInput.ClickButtonDown
- Shift + Right Click will trigger
GvrControllerInput.AppButtonDown
- Shift + Ctrl will trigger
GvrControllerInput.IsTouching
and we will print out the position we’re touching on in the Touchpad.
The first 2 inputs are easy. We press the button and we run some code.
What’s more interesting is how we deal with our touch position. In the Daydream Controller, the TouchPad works in a 2D grid from the values of 0 to 1.
Here is an artistic rendering of the positions of the TouchPad:
Masterful I know. My talent is WASTED being a Software developer!
What’s interesting to note here is that:
5, 0.5
is the center of our TouchPad- The leftmost
X
value for the TouchPad is0
, while the rightmost value is1
- Important: The topmost
Y
value for the TouchPad is1
, while the bottom-most value is0
.
I want to reiterate the last bullet point, the topmost value for y is 0. When I first started playing around with the TouchPad, I had an impression that the top value for y
is 1
. It’s not!
Now we understand more about the inputs that are available for us. Let’s dive a bit more into the TouchPad API.
Specifically, one thing that could be interesting to see done is swiping on the TouchPad. There are different ways in which we can detect a Swipe motion, however, I’m going to take a simple approach that I found in the Unity Forum: Swipe all Directions Touch and Mouse.
The idea is that we keep track of our starting position of where we first touched the TouchPad and then once we let go of the TouchPad, we’ll use the last position we were touching to calculate the direction that the user swiped in.
Now there’s a problem with this which becomes very apparent when we test this on the emulator: we must let go of the TouchPad!
Which means if we never let go of the TouchPad, we’ll never detect a swipe motion, or we can easily change a swipe left motion to be a swipe up motion.
I’m not going to look too much into this problem and just proceed with a simple implementation of a 4-direction swiping (up, right, down, left).
Here’s what the swiping code based off of the earlier example for PlayerInput
:
using UnityEngine;
public class PlayerInput : MonoBehaviour
{
public float SwipeThreshold = 0.5f;
private Vector2 _startingPosition; // tracks our starting position
private Vector2 _currentPosition; // tracks the last position touched
private bool _startedTouch; // tells us if we started swiping
void Start ()
{
_startedTouch = false;
_startingPosition = GvrControllerInput.TouchPosCentered;
_currentPosition = GvrControllerInput.TouchPosCentered;
}
void Update ()
{
if (GvrControllerInput.AppButtonDown)
{
print("Click App button down");
}
if (GvrControllerInput.ClickButtonDown)
{
print("Click Touchpad");
}
if (GvrControllerInput.IsTouching)
{
if (!_startedTouch)
{
// Start our swiping motion
_startedTouch = true;
_startingPosition = GvrControllerInput.TouchPos;
_currentPosition = GvrControllerInput.TouchPos;
}
else
{
// Tracks our position of where we're swiping
_currentPosition = GvrControllerInput.TouchPos;
}
}
else
{
if (_startedTouch)
{
// Let go of our touchpad, see if we made any swiping motions
_startedTouch = false;
Vector2 delta = _currentPosition - _startingPosition;
DetectSwipe(delta);
}
}
}
// Prints out the swipe direction (if any) based off of the Vector2 representation of
// the direction swiped
private void DetectSwipe(Vector2 delta)
{
float y = delta.y;
float x = delta.x;
print(delta);
// x = 0 is far left of touchpad
// y = 0 is far top of touchpad
if (y > 0 && Mathf.Abs(x) < SwipeThreshold)
{
print("Swiped down");
}
else if (y < 0 && Mathf.Abs(x) < SwipeThreshold)
{ print("Swiped up"); } else if (x > 0 && Mathf.Abs(y) < SwipeThreshold)
{
print("Swiped right");
}
else if (x < 0 && Mathf.Abs(y) < SwipeThreshold)
{
print("Swiped left");
}
}
}
Variables Introduced
The variables introduced here are all used to help us detect a swipe direction. Here are what we are using to do this:
private Vector2 _startingPosition
– Tells us the location on the TouchPad of where we first touchedprivate Vector2 _currentPosition
– Because there is no event listener for us to use to detect that we’re just released the TouchPad, we must track the last position touched as the player slides their finger across the TouchPad.private bool _startedTouch
– Just like, because of the previous variable, we need to know if we started swiping, otherwise we won’t know where to set our starting position.public float SwipeThreshold
=0.5f
– A value used to figure out an acceptable range we get to use when swiping left and right.
Walking Through the Code
Now that we talked a bit about the variables used, let’s see how we can use it to detect a simple swipe.
- In
Update()
, when we detect that the player is touching down on the TouchPad, we’ll set_startedTouch
to betrue
and set our_startingPosition
. - Next time around, when the player starts to move their fingers because we set
_startedTouch
to betrue
, we’ll go to theelse
statement and track the position the player is at in_currentPosition
. - This continues forever until the player lets go of the TouchPad. The moment that happens, we subtract our
_currentPosition
with our_startingPosition
to get the direction that we “swiped”. We give thisvector2
toDetectSwipe()
. - In
DetectSwipe()
, we look at the direction or the “delta” of the current position – the starting position. With this, we use the logic provided by the forum post. We would check if ourx
(ory
) value is above or below0
and if they are, we’ll check to see if oury
(orx
) value is below a certain threshold and if these conditions are met, we would detect a swipe.
There we go! Now we have an implementation of swiping for our TouchPad! This was originally made for mobile screens, but the same principles can be applied to our TouchPad.
Conclusion
That’s going to be it for a basic introduction with the controller
APIs.
In the next post, we’re going to start looking into seeing how we can use the same swiping code to implement movement.
The concept is similar to what we did with swiping, but we’ll soon discover that it’s going to be a little bit more complex than you might expect!