Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

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

0.00/5 (No votes)
27 May 2018CPOL5 min read 1.5K  
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:

  1. Touchpad button press
  2. App button press
  3. 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

  1. In the game hierarchy, select Player (right now, it doesn’t really matter which) and create a new Script. Let’s call it PlayerInput

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

C#
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:

  1. Shift + Left Click will trigger GvrControllerInput.ClickButtonDown
  2. Shift + Right Click will trigger GvrControllerInput.AppButtonDown
  3. 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:

Image 1

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 is 0, while the rightmost value is 1
  • Important: The topmost Y value for the TouchPad is 1, while the bottom-most value is 0.

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:

C#
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:

  1. private Vector2 _startingPosition – Tells us the location on the TouchPad of where we first touched
  2. private 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.
  3. 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.
  4. 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.

  1. In Update(), when we detect that the player is touching down on the TouchPad, we’ll set _startedTouch to be true and set our _startingPosition.
  2. Next time around, when the player starts to move their fingers because we set _startedTouch to be true, we’ll go to the else statement and track the position the player is at in _currentPosition.
  3. 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 this vector2 to DetectSwipe().
  4. 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 our x (or y) value is above or below 0 and if they are, we’ll check to see if our y (or x) 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!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)