Copy link to clipboard
Copied
Hello,
I'm using the GameInput class on OUYA to use the controllers. When calling GameInput.numDevices, I get 1 (for the controller I have connected), but when asking GameInput.getDeviceAt(0), I get a null.
I've tried with AIR 3.7 and 3.8 beta. Is there anything I can do to fix this?
Thank you in advance!
Could you please share your code. Could it be that the GameInput object is goiing out of scope and garbage collected?
Copy link to clipboard
Copied
Hello,
GameInput.getDeviceAt(0) is working very fine. Please find the .apk and a sample project attached in the below link:
https://www.dropbox.com/sh/0e4tef1wh1zdhlj/xozQLrNJJE
Please try it and share your result. Also, please use -swf-version>=20(if not using) while using GameInput API's.
Regards,
Nimit
Copy link to clipboard
Copied
Hello nimitja, and thanks for your fast response
Your sample worked on the third try for some reason (black screen before that). After that, I got a white screen with text. Looking at your code, I see that the text gets populated on the GameInputEvent.DEVICE_ADDED listener. For some reason, that listener never gets called in my code, although querying GameInput still returns numDevices == 1.
I aded the "-swf-version=20" to the compiler, but nothing changed.
I'll try recompiling your project to see if it's some kind of environment problem, as I don't know what else to check.
Thank you!
Copy link to clipboard
Copied
Could you please share your code. Could it be that the GameInput object is goiing out of scope and garbage collected?
Copy link to clipboard
Copied
I will when I arrive at home, but it was something like:
class Main {public function Main() { var gameInput = new GameInput(); if (gameInput.numDevices > 0) { trace("Device: " + gameInput.getDeviceAt(0)); } gameInput.addEventListener(GameInputEvent.DEVICE_ADDED, onDevideAdd);
// Initialize Starling...
}
public function onDeviceAdd(event:GameInputEvent) {
trace("Device name: " + event.name);
}
}
GameInput going out of scope maybe has something to do with the listener never getting called, but not with the first trace returning "Device: null".
I'll try with a static version later, but as said, that doesn't explain the first result (unless the GC is doing some magic I don't know about, of course)
Thank you both for your responses
Copy link to clipboard
Copied
In the end, the garbage collection was the problem (making everything static worked), although I still get null for the first part of the code (getDeviceAt(0) returns null even when numDevices is 1). If I do the getDeviceAt() on the DEVICE_ADDED listener, I correctly get an object.
Thank you all for your help!
Copy link to clipboard
Copied
We are able to reproduce the getDeviceAt(0) null issue for the first part of the code.
Thanks for reporting,
Nimit
Copy link to clipboard
Copied
Nice!
Also, while you´re at it, I have found other inconsistencies, not sure if this is intended behavior.
With the same code, on Windows I get numDevices == 0 when starting the app, then one device is added and I get numDevices == 1.
On OUYA, I get numDevices == 1 when starting the app, then one device is added and I get numDevices == 1.
Both behaviors cannot be right
Also, on Windows, the controller that's being added is not connected to my computer (I don't even have it anymore), is just registered with Windows. I think that's also wrong (DEVICE_ADDED should be fired for connected devices, isn't it?)
Thanks again!
Copy link to clipboard
Copied
I just tried the numDevices property for OUYA with and without device and it is working very fine. Could you please clean the project and try to trace the GameInput.numDevices in your application again.
Regards,
Nimit
Copy link to clipboard
Copied
Is this a known bug then? GameInput.getDeviceAt( 0 ) always (errenously, as GameInput.numDevices returns 1) returns null for me if the gamepad is already connected when the app is launched.
However if the gamepad is disconnected, then the app is launched, then the gamepad is connect GameInput.getDeviceAt( 0 ) returns the expected GameInputDevice (after DEVICE_ADDED is triggered).
Is there any way around this? It's such a pain to disconnect and reconnect the gamepad every launch.
FYI this is with the adl debug window on a Mac, with a PS3 pad via bluetooth.
Copy link to clipboard
Copied
Please always put GameInput.getDeviceAt(0) after the DEVICE_ADDED listener. It should work then.
Regards,
Nimit
Copy link to clipboard
Copied
Thanks for the reply (especially as its Sunday!)
You can only get DEVICE_ADDED when connecting an as-yet unconnected controller though, right? What about the case in which the controller is already connected to the OS before the app is launched?
Copy link to clipboard
Copied
If you put the GameInput.getDeviceAt(0) under handleDeviceAttached function which is writtten at gameInput.addEventListener(GameInputEvent.DEVICE_ADDED, handleDeviceAttached) then it should work but if it is not working then it is a bug. In that case, could you please report a bug over at bugbase.adobe.com with AIR SDK version and other important information, this will help us to resolve the issue quickly.
-Nimit
Copy link to clipboard
Copied
As you've described it works perfectly fine. BUT in order to get GameInputEvent.DEVICE_ADDED to trigger, you have to connect a gamepad that's not previously connected while the app is running - right?
What about in the use case where a gamepad is already connected to the system before the app is launched? Then GameInputEvent.DEVICE_ADDED is never triggered, because the device is already connected.
Related to the above, if you launch the app with no devices connected GameInput.numDevices returns 0 (as it should). If you launch the app with a device already connected GameInput.numDevices returns 1 (as it should), but
GameInput.getDeviceAt(0) returns null (as it shouldn't?)
Copy link to clipboard
Copied
1. Related to the above, if you launch the app with no devices connected GameInput.numDevices returns 0 (as it should). If you launch the app with a device already connected GameInput.numDevices returns 1 (as it should), but GameInput.getDeviceAt(0) returns null (as it shouldn't?) - This is a known bug and we are investigating on this.
2.If gamepad is already connected to the system before the app is launched? Then GameInputEvent.DEVICE_ADDED is never triggered, because the device is already connected - Please a;ways put the GameInputEvent.DEVICE_ADDED in the constructor, then it should get trigger.
Regards,
Nimit
Copy link to clipboard
Copied
>This is a known bug and we are investigating on this.
Thanks for the information.
>Please a;ways put the GameInputEvent.DEVICE_ADDED in the constructor, then it should get trigger.
The constructor for what? If I add:
var gameInput:GameInput = new GameInput();
gameInput.addEventListener( GameInputEvent.DEVICE_ADDED, function( event:GameInputEvent ):void{ trace( '!' ); } );
Too early in the Main (or Default Application) Class, it doesn't fire even under normal conditions. However if I wait a few frames before executing this code it works as described above (when connecting a device that was previously unconnected when the app launched).
Are you saying GameInputEvent.DEVICE_ADDED will trigger for a device that's already connected before the app is launched?
Copy link to clipboard
Copied
Yes, if the device is already connected with the console and app is launched, then the DEVICE_ADDED listener should get trigger. Could you please share your sample project so that I will give it a try.
Regards,
Nimit
Copy link to clipboard
Copied
You're right! It does do that and is the expected behaviour.
It definitely didn't work for me with the above code at some point - so either an environmental change or a code oversight - either way, sorry for bothering you, and thanks for the feedback!
Copy link to clipboard
Copied
Hello,
I've been struggling with the exact same issue. I have tried AIR 3.7 and 3.8 beta - no matter what I do I can't get my Ouya to recognise the controller at the start of the app, I have to turn the controller off and on again (at which point I get a DEVICE_ADDED event as expected and all is fine).
I have an example project exhibiting the problem, and can't see what's going wrong. The output I get is:
SUPPORTED: true (isSupported == true)
NUMBER OF DEVICES: 1 (numDevices. If I try to getDeviceAt(0) I get null)
[object GameInput] (checking that my _gameInput = GameInput is actually giving a valid object)
When I turn the controller off and on again, I get:
REMOVED! (DEVICE_REMOVED event)
NUM DEVICES: 1
NAME: OUYA Game controller
My code is as follows:
package myPackage {
import flash.events.GameInputEvent;
import flash.text.TextField;
import flash.ui.GameInput;
import flash.ui.GameInputDevice;
import net.flashpunk.Engine;
import net.flashpunk.FP;
public class MyGame extends Engine {
private static var _gameInput: GameInput;
private static var _gameInputDevice: GameInputDevice;
private static var tf: TextField;
public function MyGame() {
super("tgg", GC.SCREEN_WIDTH, GC.SCREEN_HEIGHT, GC.FRAME_RATE, GC.FIXED_FRAME_RATE, false);
tf = new TextField();
tf.textColor = 0xFFFFFF;
tf.width = 800;
tf.height = 1024;
tf.appendText("\nSUPPORTED: " + GameInput.isSupported);
if(GameInput.isSupported)
{
_gameInput = new GameInput;
tf.appendText("\nNUMBER OF DEVICES: " + GameInput.numDevices);
tf.appendText("\n" + _gameInput);
_gameInput.addEventListener(GameInputEvent.DEVICE_ADDED, onDeviceAdded);
_gameInput.addEventListener(GameInputEvent.DEVICE_REMOVED, onDeviceRemoved);
}
}
override public function init():void {
super.init();
stage.addChild(tf);
}
public function onDeviceAdded(e: GameInputEvent = null): void
{
tf.appendText("\nNUM DEVICES: " + GameInput.numDevices);
try
{
_gameInputDevice = GameInput.getDeviceAt(0);
tf.appendText("\nNAME: " + _gameInputDevice.name);
}
catch(e: Error)
{
tf.appendText("\n" + e);
}
}
public function onDeviceRemoved(e: GameInputEvent = null): void
{
tf.appendText("\nREMOVED!");
}
}
}
Ignore the flashpunk stuff - that just calls the init() function which adds the tf to the stage and should have no other bearing on anything (I get the same results in a non-FP project).
Project zip: https://dl.dropboxusercontent.com/u/738861/controllertest.zip
Please, if you can help me to get this working or see what I might be doing wrong I would be very grateful!
Copy link to clipboard
Copied
Try making a brand new project (using no external libraries or anything non-vanilla) in order to reproduce the 'bug'. When I did this it magically started working and has worked ever since, so I was clearly overlooking some minor detail.
Copy link to clipboard
Copied
Huh. Well... it worked o_O
I have no idea what the problem is/was, but it works in a new project. I'll have a play around and see if I can figure out what I was doing differently in the other one. For the curious, the code of the new project:
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.GameInputEvent;
import flash.text.TextField;
import flash.ui.GameInput;
import flash.ui.GameInputDevice;
/**
* ...
* @author Dave
*/
public class Main extends Sprite
{
private static var _gameInput: GameInput;
private static var _gameInputDevice: GameInputDevice;
private var tf: TextField;
public function Main():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
tf = new TextField;
stage.addChild(tf);
tf.textColor = 0;
tf.width = 1024;
tf.height = 1024;
tf.appendText("\nisSupported: " + GameInput.isSupported);
if(GameInput.isSupported)
{
_gameInput = new GameInput;
_gameInput.addEventListener(GameInputEvent.DEVICE_ADDED, onDeviceAdded);
_gameInput.addEventListener(GameInputEvent.DEVICE_REMOVED, onDeviceRemoved);
}
}
public function onDeviceAdded(e: GameInputEvent = null): void
{
tf.appendText("\nDEVICE ADDED");
tf.appendText("\nnumDevices: " + GameInput.numDevices);
_gameInputDevice = GameInput.getDeviceAt(0);
tf.appendText("\ngetDeviceAt(0): " + _gameInputDevice);
}
public function onDeviceRemoved(e: GameInputEvent = null): void
{
tf.appendText("\nDEVICE REMOVED");
}
}
}
Thanks!
Copy link to clipboard
Copied
Did it really work? Even at repeat runs?
I find that it works the first time but it doesn't work again anymore. It's like this:
Run app first time:
1. One device found
2. Device "added", it's a proper device
If I re-compile and run again, this happens:
1. One device found
2. Device exists but is null
This continues until I remove the gamepad (or disconnect it in case of OUYA's own controllers) and connect again. It's as if AIR is detecting a device the first time it is ran, but never again.
I'll produce some testing code, but so far I've encountered this problem with *minimal* code, including in the latest AIR version.
Copy link to clipboard
Copied
I've given it an exhaustive test by running the app directly from the console - that seems to work perfectly every time. I will try compiling freshly each time and edit this post later to let you know how it goes with that.
Copy link to clipboard
Copied
I'm running into this issue as well with the NVidia Shield, numDevices = 1, but getDeviceAt(0) is always null.
The Shield includes a gamepad which is permanently connected, so there is no ability to disconnect it.
After some testing, I've found the following:
1. If I init the GameInput API's immediately, in my document class, I do get the DEVICE_ADDED event. and getDeviceAt(0) is valid.
2. If I wait to init GameInput, until my game has started, then DEVICE_ADDED is never fired, numDevices == 1, but getDeviceAt(0) is always null
Copy link to clipboard
Copied
I too have found the same behaviour; the initialisation MUST be in the document class and called immidiately. Anywhere else and it fails to fire DEVICE_ADDED until the controller is disconnected and reconnected.