This codelab will teach you how to extend an existing Unity game to run on Android TV.  This includes gamepad support, player configuration and other key features for having a great game on Android TV.  In this section, we will set up the Unity environment with all of the materials you will need to complete this codelab.

What you’ll learn

What you’ll need

Game Summary

For this codelab, we'll be using a simple and entertaining game, called "Nightmares". This is a standard sample game from Unity showing many of the basic game making techniques.  We're going to skip their tutorial (feel free to run through it later!), and jump right into making it work on Android TV.

 Key features of note are:

How will you use use this tutorial?

Read it through onlyRead it and complete the exercises

How would you rate your experience with building Unity apps?

NoviceIntermediateProficient

How would you rate your experience with building Android apps?

NoviceIntermediateProficient

First you need the unity asset package containing the sample game.  You can download this here: Download codelab sample unitypackage file

First, let's build and run the game.  From there, we'll add gamepad support.

Start Unity

  1. Start Unity!  If you have not developed an Android application with Unity before, make sure you configure the Android SDK within Unity.  In Unity, click Preferences > External Tools > Android SDK Location, then select the folder where you downloaded and unzipped the Android SDK.

Import the game assets

Import the sample game scenes and assets into your project:

  1. Click Assets > Import Package > Custom Package.
  2. Select the androidTV_nightmares_starter.unitypackage file you downloaded
  3. Click Import.

Once it is imported, open the game scene in the editor and play.

  1. In the Project explorer, select the Assets/Scenes folder and double click on Level01.unity.
  2. Click the play button in the editor.  The movement keys are the standard WASD or the arrow keys.  Use the mouse to aim and click to shoot.

Once everything is working, click play again to stop the playback, and save the scene and project.

Configure the Android player

  1. Configure Unity to build an Android application:
  1. Add the game scene to the build:

Configure Bundle Identifier

Click on Player Settings..., expand the “Other Settings” section by clicking on it.

Enter the bundle identifier.  The bundle identifier should be unique, and follows .Net namespace (or Java package) naming rules.  Typically this is of the form: com.<yourcompany>.<appname>.  

Configure Android TV properties

  1. In the Other Settings panel set:
  1. Android TV Compatible  - Checked
  2. Android Game - Checked
  3. Android Gamepad support - Requires Gamepad
  1. In the Icon panel, make sure Enable Android Banner is checked.  Set the banner texture to  Assets/NightmaresBanner.png

Save and Run

  1. Save your project!  Better safe than sorry :)
  2. Connect a device build and run!  When prompted for a name for the APK file, enter nightmares.apk.

Congratulations! If you can play the starter project game on your Android TV, you should be able to move with the remote control directional pad, or the left joystick of the gamepad.  However, since there is no mouse on the TV, you can't turn to aim.  Let's take care of that next!

Troubleshooting

Even the most simple things can have gotchas!  Here are a couple and what to do about it.  If you’re still having problems ask for help!

Issue

Solution

Issue: Error building Player: UnityException: Bundle Identifier has not been set up correctly

Solution: Set the bundle identifier to something other than the default.  This is in the player settings > Other Settings section.

Unity virtualizes the input controllers (see http://docs.unity3d.com/Manual/ConventionalGameInput.html for more information).  The default configuration is only aware of the left joystick of the game controller as well as the buttons.  As a result, the first thing we need to do is configure the right joystick input so we can aim.  We'll add support for firing using the right trigger too.

As you step though these configuration steps, you can refer to http://docs.unity3d.com/Manual/class-InputManager.html for context on what the different fields control.

Open the Input Manager configuration

  1. Click Edit > Project Settings > Input to open the Input Manager inspector tab.
  2. In the inspector window, expand Axes to show all the configured input.
  3. We need to add 3 more.  Change the Size property from 18 to 21.  Notice that the list grows by copying the last value (Cancel) into the new slots.

Add Right Trigger firing

To make the instructions easier, we'll work from the bottom of the list up to configure the inputs.

Expand the last element in the list.  Set the properties based on this list.  The trigger is actually an analog input, so the properties related to buttons are empty.

Add Right joystick X axis

Expand the second to last element in the list  Set the properties based on this list.  

Add Right joystick X axis

Expand the third to last element in the list  Set the properties based on this list.  

Save the project

Now the input manager is configured to get input from the gamepad.  Next, let's use these new inputs in the scripts.

Now that we have the input configured, let's change the player movement script to use them to turn and aim.  Since it is nice to test the game in the editor, we want to do this in a way that does not break input from the mouse.

  1. In the Project explorer, open Assets/Scripts/Player and double click on PlayerMovement.cs.
  2. Find the method FixedUpdate().
  3. Create a new method TurningJoystickAware() by pasting the following code below FixedUpdate():
    void TurningJoystickAware()
    {
        // Check for mouse presence.  Android TV has no mouse.
        if (Input.mousePresent)
        {
            // Call the existing turning method
            Turning();
        }
        else {
            // Get the joystick input

            float mh = Input.GetAxisRaw("Joystick_R_X");
            float mv = Input.GetAxisRaw("Joystick_R_Y");

            // Don't do anything if the joysticks are not moved
            if (Mathf.Abs(mh) > Mathf.Epsilon ||
                Mathf.Abs(mv) > Mathf.Epsilon)
            {
                Quaternion newRotation = Quaternion.Euler(
                    new Vector3(
                        playerRigidBody.transform.eulerAngles.x,
                        Mathf.Atan2(mh, mv) * Mathf.Rad2Deg, 
                        playerRigidBody.transform.eulerAngles.z));
         
                // Use Slerp to have smooth rotation.
                playerRigidBody.rotation = 
                    Quaternion.Slerp(playerRigidBody.rotation,
                        newRotation, Time.deltaTime * Speed);
            }
        }
    }
  1. Now replace the call in FixedUpdate() to Turning() with a call to TurningJoystickAware().  When you are done, FixedUpdate will look like:
    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        Move(h, v);
        TurningJoystickAware();
        Animating(h, v);
    }

Save the file then switch back to the Unity Editor.  Select File > Build & Run and test out that moving and aiming now work with the gamepad.

 We need to add the checking of the right trigger on the gamepad to the shooting script.

  1. In the Project explorer, open Assets/Scripts/Player and double click on PlayerShooting.cs and find the method Update().
  2. Add a new variable that checks for the Fire1 button or the right trigger:
bool triggered = Input.GetButton ("Fire1") ||
   Mathf.Abs(Input.GetAxisRaw ("Gamepad_R_Trigger")) > Mathf.Epsilon;
  1. Modify the "if" statement to use the variable instead of checking for the button:
if(triggered && timer >= timeBetweenBullets &&
   Time.timeScale > Mathf.Epsilon)

Save the script, switch back to the Unity editor, and build and run to test it out!

Since we are using the gamepad to control our player, we want to pause the game if the gamepad is disconnected.  There is already a pause screen (shown if you hit the back button), so we can trigger that when the gamepad disappears.

  1. In the Project explorer, open Assets/Scripts/Managers and double click on GameOverManager.cs.
  2. At the top of the class, add a new member variable to record if the gamepad is present.
    private bool hasGamepad;
  1.  Initialize hasGamepad in Awake().  The complete Awake() method should look like:
void Awake()
{
        anim = GetComponent<Animator>();
        hasGamepad = DetectGamepad();
}
  1. Implement DetectGamepad().   The detection is done by iterating over the names of the joysticks.  If a joystick is present, its name will be in the list.  If it is disconnected, the entry will be null or empty in the list.   Below Awake() method, paste the DetectGamepad() method:
bool DetectGamepad()
{
    bool found = false;
    foreach(string name in Input.GetJoystickNames())
    {
        found = !string.IsNullOrEmpty (name);
    }
    return found;
}
  1. Add the check to see if the gamepad is disconnected, and then pause.  Paste this code in Update(), just above the comment "// check for Pause"
// check for disconnected gamepad
bool detectedGamepad = DetectGamepad();
if (hasGamepad && !detectedGamepad)
{
    PauseGame();
}
hasGamepad = detectedGamepad;
  1. Save the script, go back to the Unity editor.  Save the project and build and run!  This time, once the game starts, remove the battery pack from the gamepad, and the game should pause.  Turn on the gamepad again, and press a button to resume the game.

Hopefully you found this codelab an informative introduction into how to build a game for Android TV using Unity.  For more detailed information refer to:

Distributing to Android TV: https://developer.android.com/distribute/googleplay/tv.html

Designing for Android TV: http://www.google.com/design/spec-tv/android-tv/introduction.html

Getting started with Android Development with Unity: http://docs.unity3d.com/Manual/android-GettingStarted.html