Note: Make a backup of your AndroidManifest.xml in Assets/Plugins/Android/AndroidManifest.xml before importing the OuyaSDK-Core.unitypackage, Unity-OuyaSDK-Forge.unitypackage, and Unity-OuyaSDK-Xiaomi.unitypackage.

Note: Make a backup of your signing key in Assets/Plugins/Android/assets/key.der before importing the OuyaSDK-Core.unitypackage.

Note: Make a backup of your icons in Assets/Plugins/Android/res/drawable/app_icon.png and Assets/Plugins/Android/res/drawable-xhdpi/ouya_icon.png before importing the OuyaSDK-Core.unitypackage.

Source

Overview

This document covers importing the core package, installing dependencies, building, and publishing your game to Cortex.

Intro

The ouya-core.unitypackage contains a static access class for accessing input and the Cortex SDK API for the Unity game engine. The input API makes it possible to build your game and without needing to rebuild will automatically add future support for new controllers and devices while still correctly mapping for your game. The input API also adds new features like being able to consistently know which controller maps to a player number. And if a controller disconnects and reconnects it will maintain the same player number. The input API makes it possible to detect if a controller has been disconnected.

This input API is targeted for Cortex and is not maintained as a cross-platform input system.

Updating

Download OuyaSDK-Core.unitypackage from Releases. Import the OuyaSDK-Core.unitypackage to update the plugin. In the import dialog uncheck the AndroidManifest.xml, signing key and icons if you don't want to replace your customizations. The imported plugin will be ready to Build and Run as recompiling the Java and Native plugins are no longer required now that the package includes the prebuilt libraries.

Setup

Open your game or a new project.

Note: Make sure that your project path does not contain spaces in order to be compatible with the NDK compiler.

Icons

If the icons have already been customized, there's no need to import the icons and replace with the sample icons.

Signing key

Importing the signing key is a placeholder for where to place the signing key downloaded from the developer portal. The signing key is used in in-app-purchase encryption and decryption. The in-app-purchase API will not work until you create a game in the developer portal to download the game's signing key. Be cautious when importing updates to not replace this file.

Note (ODK 1.0.14.1): The signing key was moved to be compatible with 3rd party plugins.

Assets/Plugins/Android/assets/key.der

Orientation

Within the Player Settings, Android Tab, set the default orientation to Landscape Left.

OuyaGameObject.cs

Add the OuyaGameObject to your initial loading scene. It uses DontDestroyOnLoad so you only want one instance of the OuyaGameObject. It handles communication between Java to C#. Select the OuyaGameObject in the SceneView and in the inspector, the OUYA Plugin Init Values field will be visible. Add an entry for tv.ouya.developer_id that corresponds to your developer uuid in the developer portal.

Resource files contain key/value pairs for looking up localized strings given the key value.
Using the OuyaSDK API, invoke OuyaSDK.getStringResource("app_name") to return the localized string for the key app_name which in this example would return 安卓 出口 when the language is detected as Simplified Chinese, i.e. on the Xiaomi box.

Other Player Settings

In the Android Player Settings and within the Other Settings subgroup, here you can enter your package identifier from the developer portal into the bundle id field. Make sure the minimum API level field to 16.

Dependencies

The Cortex Plugin has dependencies on the Android SDK for packaging and deploying Android applications.

The Cortex Plugin includes prebuilt Java and Native plugins, recompiling the Java and Native plugin is no longer required.

Intellisense

To enable intellisense for UNITY_ANDROID and not UNITY_EDITOR, be sure to edit the project settings and remove the UNITY_EDITOR from the debug symbols.
If Unity regenerates the solution/project, the debug symbols will be readded which will need to be removed again to get intellisense back.

Initialization

Initialization is handled by the OuyaGameObject being placed in your initial scene.

Make sure that before invoking other OuyaSDK methods than isIAPInitComplete returns true. This gives time for the Java to initialize before accessing the controller, button names, button images, products, purchase, receipts, and toggling cursor visibility.

OuyaController.BUTTON_MENU

Note: Be sure to check for button states with GetButtonDown and GetButtonUp. Just checking for the GetButton state will never catch the event in time because the down and up event fire within the same frame.

Check if controller is connected

OuyaInput exposes a static method to check if the controller is connected.

C#

#if UNITY_ANDROID && !UNITY_EDITOR
//@returns true if the player number is connected
//@returns false if the player number is disconnected
bool OuyaSDK.OuyaInput.IsControllerConnected(int playerNum);
#endif

Hide the mouse cursor

In some cases you may want to hide or show the mouse cursor. The showCursor static method on OuyaController toggles cursor visibility.

Set Safe Area

Part of the content submission guideline rules is that all important information needs to be in the safe zone. The safe area can be adjusted by passing an amount when calling OuyaSDK.setSafeArea(amount).

The general process for using the Community Content API is register listeners and wait for initialization.

IContentInitializedListener

One way to check if Community Content has been initialized is to implement the IContentInitializedListener interface.
Be sure to register/unregister the listener during the Awake and OnDestroy events.
ContentInitializedOnInitialized is invoked when the OuyaContent becomes accessible.
ContentInitializedOnDestroyed is invoked when the OuyaContent has been destroyed.

OuyaContent

OuyaContent is the entry point for accessing the Community Content API.
OuyaUnityPlugin provides a reference to the OuyaContent object.
Make sure to wrap the OuyaContent accessor with using to ensure the JNI reference is disposed.

isAvailable

Before accessing Community Content, make sure the API is available to the gamer.
The Community Content API won't be available if an age gate is active for the gamer.

C#

bool isAvailable = ouyaContent.isAvailable();

isInitialized

One way to check if Community Content has been initialized is to invoke isInitialized.

C#

if (ouyaContent.isInitialized())
{
}

IContentDeleteListener

Implement the IContentDeleteListener interface to receive the callbacks from deleting an OuyaMod community content object.
Be sure to register/unregister the listener during the Awake and OnDestroy events.
ContentDeleteOnDeleted is invoked when the OuyaMod has been deleted.
ContentDeleteOnDeleteFailed is invoked when the OuyaMod deletion has failed.
The listener callbacks occur after OuyaUnityPlugin.contentDelete is invoked.

IContentDownloadListener

Implement the IContentDownloadListener interface to receive the callbacks from downloading an OuyaMod community content object.
Be sure to register/unregister the listener during the Awake and OnDestroy events.
ContentDownloadOnComplete is invoked when the OuyaMod has finished downloading.
ContentDownloadOnProgress is invoked when the OuyaMod download is in progress.
ContentDownloadOnFailed is invoked when the OuyaMod download has failed.
The listener callbacks occur after OuyaUnityPlugin.contentDownload is invoked.

IContentInstalledSearchListener

Implement the IContentInstalledSearchListener interface to receive the callbacks from searching for installed OuyaMod community content object.
Be sure to register/unregister the listener during the Awake and OnDestroy events.
ContentInstalledSearchOnResults is invoked when the search for OuyaMod installed content has finished.
ContentInstalledSearchOnError is invoked when the OuyaMod search has failed.
The listener callbacks occur after OuyaUnityPlugin.getOuyaContentInstalled is invoked.

IContentPublishedSearchListener

Implement the IContentPublishedSearchListener interface to receive the callbacks from searching for published OuyaMod community content object.
Be sure to register/unregister the listener during the Awake and OnDestroy events.
ContentPublishedSearchOnResults is invoked when the search for OuyaMod published content has finished.
ContentPublishedSearchOnError is invoked when the OuyaMod search has failed.
The listener callbacks occur after OuyaUnityPlugin.getOuyaContentPublished is invoked.

IContentPublishListener

Implement the IContentPublishListener interface to receive the callbacks from publishing an OuyaMod community content object.
Be sure to register/unregister the listener during the Awake and OnDestroy events.
ContentPublishOnSuccess is invoked when the OuyaMod has published successfully.
ContentPublishOnError is invoked when the OuyaMod publish has failed.
The listener callbacks occur after OuyaUnityPlugin.contentPublish is invoked.

IContentSaveListener

Implement the IContentSaveListener interface to receive the callbacks from saving an OuyaMod community content object.
Be sure to register/unregister the listener during the Awake and OnDestroy events.
ContentSaveOnSuccess is invoked when the OuyaMod has saved successfully.
ContentSaveOnError is invoked when the OuyaMod save has failed.
The listener callbacks occur after OuyaUnityPlugin.saveOuyaMod is invoked.
Saved OuyaMod content will return in the installed Community Content searches.
The saved OuyaMod content needs to be published to show in the published search results.

IContentUnpublishListener

Implement the IContentUnpublishListener interface to receive the callbacks from unpublishing an OuyaMod community content object.
Be sure to register/unregister the listener during the Awake and OnDestroy events.
ContentUnpublishOnSuccess is invoked when the OuyaMod has unpublished successfully.
ContentUnpublishOnError is invoked when the OuyaMod unpublish has failed.
The listener callbacks occur after OuyaUnityPlugin.contentUnpublish is invoked.

IResumeListener

Implement the IResumeListener interface to receive the resume callback.
When the Community Content rate and flag dialogs are closed the resume callback will indicate the game can continue.
Be sure to register/unregister the listener during the Awake and OnDestroy events.
OuyaOnResume is invoked when the game has been resumed.

Create

The OuyaContent object is used to create content.
The OuyaMod content must be saved before it will be returned by searching for installed content.
The OuyaMod content must be published before it will be returned by searching for published content.

Examples

Import the Examples package. From the menu item Assets->Import Package->Custom Package… and browse to the "ouya-examples.unitypackage".

OUYA Panel

Open the OUYA Panel from the Window->Open OUYA Panel menu item.

The OUYA Panel provides a quick way to switch between examples.

Use the drop down to select the example and then click the Switch to Example button which updates the icons and package name.

Virtual Controller Example

The virtual controller example exercises the new OUYA-Everywhere input. The button names and images are now accessible from the API. And the virtual controller buttons highlight for multiple controllers for supported controllers. The right-hand JOY buttons toggle input for specific player numbers.

The Virtual Controller script displays a 2D controller with axis and buttons that highlight when the physical controller is used.

Input Test

The Input Test script displays all the axis, button up, and button down states to verify that input is correctly setup.

In App Purchase Example

The ShowProducts scene is an in-app-purchase example that uses the OuyaSDK to access gamer info, purchasing, and receipts.

Safe Area Example

The Safe Area example uses the DPAD left and right to invoke OuyaSDK.setSafeArea(float amount). Using 0.0 for the amount uses full border padding. Using 1.0 for the amount uses no border padding.

Community Content Example

The Community Content example shows how to create, edit, publish, unpublish, download, and delete Community Content.

Customization

The OUYA Plugin remains customizable and if you want to extend the Java and Native plugins there are dependencies on the Android SDK, Android NDK, and Java JDK.

Legacy OuyaPostProcessor.cs (Removed)

The OuyaPostProcessor would auto compile C++ and Java source after a detected change. However, changes to the plugin are infrequent enough making this feature not used and so it was removed. Typically you only need to compile NDK and the Java Plugin after importing an update of the plugin.

Assets/Ouya/SDK/Editor/OuyaPostProcessor.cs

Legacy OuyaUnityApplication.jar (Removed)

If you have the legacy OuyaUnityApplication.jar file make sure that it’s removed. If you forget this step, you’ll get an DEX error when building the game.

Assets\Plugins\Android\OuyaUnityApplication.jar

Legacy OuyaUnityApplication.java (Removed)

If you have the legacy OuyaUnityApplication.java file make sure that it’s removed. If you forget this step, you’ll get a Java compile error.

Assets\Plugins\Android\src\OuyaUnityApplication.java

Legacy OuyaNativeActivity.java (Removed)

If you have the legacy OuyaNativeActivity.java file make sure that it’s removed. If you forget this step, you’ll get a Java compile error.

Assets\Plugins\Android\src\OuyaNativeActivity.java

Legacy R.java (Removed)

The Core Unity Package may include example R.java files that should not be imported into your game. You may want to delete these extra files if they were imported.

Note (ODK 1.0.14.1): R.java and resources were moved to be compatible with other 3rd party plugins that also supplied this generated file.

Assets\Plugins\Android\src\tv\...\R.java

Legacy Litjson (Removed)

Litjson is a public domain 3rd party library for parsing JSON data. Android already has classes for handling JSONObject parsing and so the legacy Litjson was replaced.