Just sent this in as a bug, but I wanted to post in the forums to save people some headache as well. It seems like there's a NullPointerException in this method, so for now you might want to wrap calls to OuyaController.getControllerByPlayerId with try/catch blocks until it gets resolved.
Are you sure this is the case? I use getControllerByPlayer and I have never received a NullPointerException even in game samples that never receive an axis event. The method will return a null if you call getControllerByPlayer and pass a player number for a player that is not currently active. If you call a method (like getButton) on the returned null, then you will receive a NullPointerException.
Yes, this is a weird case that occurred only when calling getControllerByPlayer after devices were connected but before any input events have been handled by the OuyaController class (such as at application launch). I sent in a repro case to the OUYA team, and I've also changed my approach to not do things this way.
The way the current OuyaController class depends on the keyevents wouldn't work this way, but it should definitely not give you guys an NPE [-X I'll log that as a bug to fix!
@Stretcher no problem! I am glad this post wasn't useless, I was beginning to think I was the only one getting this. Do you need more info on a workaround?
If you simply want to bypass the NPE's, just wrap those calls in try/catch blocks and tell your users to wiggle the controller in the first screen. :)
I was able to get around it because I use a polling-based system for Unity to fetch current controller state at the beginning of every Unity frame. I keep controller state stored in a separate object for each controller, indexed by player number, and I use OuyaController to update the state when events occur. In my application, then I access the state objects directly to get current state instead of querying OuyaController directly.
Looking into this now, I think the problem you are seeing is that OuyaController::getAxisValue actually returns a Float object (which can be null). So if you had a line like:
float x = c.getAxisValue(OuyaController.AXIS_LS_X);
Then it would NPE if getAxisValue returns null and it tries to auto-unbox into a float.
This doesn't seem useful, so I'll change the declaration to:
public float getAxisValue(int ouyaAxis);
And have it return 0.0f if there's been no stick input yet.
I can confirm that the issue is still not fixed as of ODK 1.0.0. To better show what's happening, I created a small and very simple Android project. Build it and run it on a real Ouya hardware. You can clearly see that if you don't touch anything in your controller, it will not be detected at start because getControllerByPlayer returns null. It becomes detected only when a motion event or a key press is handled.
Not sure if it is related, but I was getting a NullPointerException from inside the ODK when calling OuyaController.getPlayerNumByDeviceId( int ) prior to any axis events. I was able to correct the problem by making sure the call to OuyaController.init( Context ) was done first.
Not sure if it is related, but I was getting a NullPointerException from inside the ODK when calling OuyaController.getPlayerNumByDeviceId( int ) prior to any axis events. I was able to correct the problem by making sure the call to OuyaController.init( Context ) was done first.
Fixed the NPE on that one :) Just returns -1 now if not init-ed
Comments