Xperia™ PLAY tutorial – Angry Mob Games’ optimisation tips using Unity’s tool chain

Hello Developer World! My name is Bogdan Iliesiu from Angry Mob Games, and in the following article, I’d like to share with you a few tips for optimising your games for the Xperia™ PLAY using Unity’s tool chain. To have your game take advantage of the Xperia™ PLAY, game developers will first need to adjust all the game controls. We at Angry Mob Games took some additional steps to make our flagship game, Guerilla Bob, feel much better integrated on the device.

Updated: check out a demo video after the jump!

So here is a quick summary of the steps we took when making Guerrilla Bob for the Xperia™ PLAY:

1. Added support for the device physical buttons and touch pad (the dual joysticks area).

2. Added key navigation for the game menus.

3. Added on-screen control tutorials showing the Xperia™ PLAY (PlayStation®-style) buttons.

4. Optimized the graphics.

In the following section, I’ll give you some more details and code samples on each of the steps above.

Adding support for the physical controls.

Unity has a great sample project, which shows you how to get input from each of the buttons. (I’m sure Unity will put it up on their website, once Unity 3.3 goes live.) For the main gameplay controls, we decided to use only the physical buttons when the Xperia™ PLAY device is slid open, and also hid all the on-screen virtual buttons. When the device slides back up, the UI is shown for the virtual buttons and we let the users control the game using the main touch screen. 

To find out when the phone is slid open, Unity implemented a bool function. It’s not an event, so we need to constantly check for that value. Here’s a short coroutine which does that:

AndroidJavaObject currentConfig = null;

//call this one in Awake()
void InitAndroidConfigLink()
{
using (AndroidJavaClass player = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
AndroidJavaObject activity = player.GetStatic<AndroidJavaObject>("currentActivity");
currentConfig = activity.Call<AndroidJavaObject>("getResources").Call<AndroidJavaObject>("getConfiguration");
}
}

IEnumerator CheckForPhoneSlidedStatus()
{
const int NAVIGATIONHIDDEN_UNDEFINED = 0;
//   const int NAVIGATIONHIDDEN_NO = 1;
const int NAVIGATIONHIDDEN_YES = 2;
int nav;
while (true)
{
nav = currentConfig.Get<int>("navigationHidden");
if (nav == NAVIGATIONHIDDEN_YES || nav == NAVIGATIONHIDDEN_UNDEFINED)
{
PhoneSlided = false;
//show controls UI
if (!LeftControlPad.gameObject.active)
{
ShowPads();
PauseButton.gameObject.active = true;
}
}
else
{
PhoneSlided = true;
//hide controls UI
if (LeftControlPad.gameObject.active)
{
SetLeftStickActive(false);
SetRightStickActive(RightStickMode.None);
PauseButton.gameObject.active = false;
}
}
yield return new WaitForSeconds(2F);
}
}

Most of the button inputs are really easy to read, and they all have certain key codes. This is the full list:

Arrow Left: Input.GetKey(KeyCode.LeftArrow)

Arrow Right: Input.GetKey(KeyCode.RightArrow)

Arrow Up: Input.GetKey(KeyCode.UpArrow)

Arrow Down: Input.GetKey(KeyCode.DownArrow)

X: Input.GetKey(“joystick button 0″)

Square: Input.GetKey(“joystick button 1″)

Triangle: Input.GetKey(“joystick button 2″)

Circle: Input.GetKey(“joystick button 3″)

Left Shoulder Button: Input.GetKey(KeyCode.LeftShift)

Right Shoulder Button: Input.GetKey(KeyCode.RightShift)

Select: Input.GetKey(KeyCode.Pause)

Start: Input.GetKey(KeyCode.Return)

Android Menu: Input.GetKey(KeyCode.Menu)

Android Back: Input.GetKey(KeyCode.Escape)

We used the four directional keys to move our character, Bob, around. To do that, we built a movement vector by using:

  directionalKeysVector.x = Input.GetAxis("Horizontal");
directionalKeysVector.y = Input.GetAxis("Vertical");
directionalKeysVector.Normalize();

To be able to do that, you also have to define that axis input name, under Project Settings->Input. The above value is standard when you start a new Unity project.

The trickiest part is getting input from the Xperia™ PLAY touch pad (the middle area with the two round sticks). It acts just like the main touchscreen input.

Here’s some code to get two vectors, one for the left area, and one for the right area of the touch pad (left and right sticks):

private void GetSecondaryTouchInputNoPhases()
{

if (AndroidInput.secondaryTouchEnabled)
{

int count = AndroidInput.touchCountSecondary;
if (count == 0)
{

if (playerControllerOne.Shooting)
{
playerControllerOne.StopShooting();
}

if (directionalKeysVector.sqrMagnitude < 0.1F)
{
leftStickVector = Vector2.zero;
playerControllerOne.MovementDirection = Vector2.zero;
}
}

for (int i = 0; i < count; i++)
{
touch = AndroidInput.GetSecondaryTouch(i);
touchPosition = touch.position;

lDiff = new Vector2(touchPosition.x - secondaryLeftStickCenter.x, 480 - touchPosition.y - secondaryLeftStickCenter.y);
rDiff = new Vector2(touchPosition.x - secondaryRightStickCenter.x, 480 - touchPosition.y - secondaryRightStickCenter.y);

leftStickDown = (lDiff.sqrMagnitude < secondaryPadRadiusInPixels * secondaryPadRadiusInPixels);
rightStickDown = (rDiff.sqrMagnitude 0.01F)
{
playerControllerOne.LookingDirection = rDiff;
}

if (!playerControllerOne.Shooting)
{

playerControllerOne.StartShooting();
}
if (count == 1)
{
if (directionalKeysVector.sqrMagnitude < 0.1F)
{
leftStickVector = Vector2.zero;
playerControllerOne.MovementDirection = Vector2.zero;
}
}
}
}

}
}

For the code above, we used the two vectors for movement and shooting directions. Please note the values for the touchpad width/height, and the various calculations were required when reading the exact touch position.

The code below uses either the arrow keys, or the touchpad left stick to move the character:

void UpdatePhoneInput()
{
if (PhoneSlided)
{
directionalKeysVector.x = Input.GetAxis("Horizontal");
directionalKeysVector.y = Input.GetAxis("Vertical");
directionalKeysVector.Normalize();
GetSecondaryTouchInputNoPhases();
}
else
{
GetPhoneTouchScreenInput();
}

if (playerControllerOne.IsControllable)
{
if (PhoneSlided)
{
if (leftStickVector == Vector2.zero)
{
if (directionalKeysVector.sqrMagnitude > 0.1F)
{
playerControllerOne.MovementDirection = directionalKeysVector;
}
else
{
playerControllerOne.MovementDirection = Vector2.zero;
}
}
}
}
}

I guess that’s all there is to it. Just make sure you turn on ‘NativeActivity’ in the Player Settings.

Adding key navigation for the game menus

We used the arrow keys plus the ‘X’ and ‘O’ buttons to navigate around the menus, much like the console games. ‘X’ seems to be standard for activating a button, and ‘O’ is for canceling and returning to a previous menu state. We also used ‘Start’ and ‘Select’ to enter the Pause menu, during gameplay.

To implement all these, we had a special button class, which stored all the neighbours for up, down, left and right. Each button had a delegate (function) for receiving focus, and one for going back to its original state. If one of its button neighbours was inactive, it would search recursively in that direction, until it found an active button to get focus.

Adding on-screen control tutorials showing the Xperia™ PLAY (PlayStation®-style) buttons

We showed some graphics of which buttons to press, depending on the game context, when showing the first tutorial. For this, we used game pad buttons artwork provided by Sony Ericsson.

Here’s what the interface looks like:

Here’s an archive with all the buttons, each as a different 3D mesh (a plane), with an optimized texture atlas. Each button has a normal and a pressed state. Feel free to use it in your game.

Optimizing the graphics

Optimizing the graphics means pumping them up, as the Xperia™ PLAY device seems to be much more powerful than the iPhone4, for example. It also does a great job handling larger textures. You would need to test your game to see how much you can push it. For Guerrilla Bob, it runs at 60FPS constantly, which is super.

The full hardware specs for the Xperia™ PLAY are here.

So I guess that’s all it takes. The rest is just your awesome game!

If you have any questions, feel free to post them here, so everybody can join the discussion.

If you’d like to see more details about our games, Guerrilla Bob and Predators, you can check out www.angrymobgames.com.

Updated: check out Guerilla Bob running on Xperia™ PLAY below:

 

More information

Comments 14

Sort by: Newest | Oldest | Most popular

  1. By SM

    #1

    Thanks alot for the post.

    I am still having some issues though.
    I followed all the directions, checking “Native Activity”. The buttons work fine, but I still cannot get any signal from the touchpad. The “AndroidInput.secondaryTouchEnabled” flag always seems to be false. Is there something I’m missing?

    • By Joe Padre

      #2

      Hi SM,
      Our Unity developer contact says:
      Is it possible that the user is trying this on an existing project that uses Unity plugins to override the manifest? If so, the result may be that the NativeActivity isn’t activated. If the user creates a new project without any existing files, enables NativeActivity and creates a small test script to read the touchpad, does it work then?
      Please check and let us know.
      Thanks,
      Joe Padre
      Sony Ericsson Developer World

    • By Joe Padre

      #3

      Hi SM,
      Trying to get an answer for you ASAP. Stay tuned.
      Thanks,
      Joe Padre
      Sony Ericsson Developer World

  2. By Jashan

    #4

    Thanks for posting this – the keycodes are extremely helpful, especially since they seem to be not documented anywhere in the Unity documentation.

    However, I’m struggling with the navigationHidden property. This always returns 1 on my Xperia Play, no matter whether the keypad is available or not. I do get a log message that the state was changed, so it doesn’t seem to be a hardware problem as the change is obviously recognized.

    Furthermore, I’m also getting the value 1 here on the Google Nexus One which doesn’t even have a keypad.

    • By Joe Padre

      #5

      Hi Jashan,
      I check with our Unity developer contact and he advises:
      This is a problem with the older european or US firmware for the PLAY. In that firmware navigationHidden wasn’t used but instead hardwareKeyboardHidden.
      Looking at an old email thread it seems 3.0.A.2.179 has this problem, but 3.0.A.2.184 does not (navigationHidden can be used).
      As for using it on a non-PLAY device (like the Nexus One) – first check that AndroidInput.secondaryTouchEnabled is true (or some other mechanism to determine whether or not it’s a PLAY, like checking if the model name includes “R800″) before detecting navigationHidden and you should be fine.
      Best regards,
      Joe Padre
      Sony Ericsson Developer World

    • By Joe Padre

      #6

      Hi Jashan,
      Trying to get an answer for you. Hang tight!
      Cheers,
      Joe Padre
      Sony Ericsson Developer World

  3. By TJ

    #7

    It’s fine I guess, the Xperia Arc doesn’t seem to be coing to the US anytime soon, I just got myself a Nexus S instead. Keep up the good work guys, I expect to be a potential customer of your 2011 products!

    • By Joe Padre

      #8

      Thanks again, TJ! We’re looking forward to having you as a Sony Ericsson user!

  4. By TJ

    #9

    Hello, do you guys ever check on here? :(

    WIll the Xperia Arc be playstation certified? I.E, will it get games from the playstation pocket like the Xperia Play?

    • By Joe Padre

      #10

      Hi TJ,
      Apologies for the delayed reply. The Xperia arc is not PlayStation certified, just the Xperia PLAY.
      Regards,
      Joe Padre
      Sony Ericsson Developer World

  5. By David Rodriguez

    #11

    What companies will the Xperia play be for?

    • By Joe Padre

      #12

      Hi David,
      In the US, the Xperia PLAY will initially be available only on the Verizon network.
      Regards,
      Joe Padre
      Sony Ericsson Developer World

  6. By TJ

    #13

    Hello, can these be mapped unto 3rd party gamepads? I love the Xperia Arc so much but I also love gaming. There is a 3rd party bluetooth controller called the icontrolpad; can these third party controllers mirror the Xperia Play’s analog sticks? Also, is the Arc PlayStation certified? In other words, will the Arc run Play games?

    Also just throwing this out there, Sony should make bluetooth gamepads for Playstation certified phones for about $40 each. It wold sell like hotcakes, I know I’d get one!

    Here’s what I mean: http://www.youtube.com/watch?v=AHKpqgv5GqU

    • By Joe Padre

      #14

      Hi TJ,
      Sorry for the delayed reply. Regarding third party game pads, the SW does not support third party joysticks.
      Regards,
      Joe Padre
      Sony Ericsson Developer World

1-14 of 14 comments.