OuyaInputManager to behave like Unity InputManager

SetsukiSetsuki Posts: 13Member
edited February 2013 in Unity on OUYA
Hello everyone,

I'm pretty sure the code I'm posting here has already been made, and maybe even already posted, but I can't find it anywhere.

If you're used, or want the down (getButtonDown) and up (getButtonUp) states to behave like Unity does (down is true only once), I made a small script for that. It's a mashup between Unity's philosophy and Ouya's, it's not deep, hardcore code ; basically, it's booleans that go true or false according to Unity's input behaviour. If you want a copycat of Unity's InputManager You'd better try @GoodHustle 's OuyaBridge https://github.com/getluky/OuyaUnityBridge


This script hasn't been approved by any of the official Ouya devs, and isn't official in any way.
it doesn't replace OuyaInputManager nor any of the SDK tools, you still need them.

How to use :
Simply attach the script to the object you want to control, configure the player number with the inspector. 
In your control script, use it as a variable. Here is an example that writes the states on the GUI :
Post edited by Setsuki on
HeroTown : free 2.5D 4-player Beat'em up for OUYA
«1

Comments

  • goodhustlegoodhustle Posts: 144Member
    Hi @Setsuki, I've been writing an implementation of this for my own use, and it has some additional features like customizable virtual axis/button names and GetKey support, etc. It isn't official either, but if you need 1:1 exactly to Unity's Input to do a quick port, you can try mine out. 

    Beast Boxing Turbo - OUYA Launch Title!
  • tgraupmanntgraupmann Posts: 2,869Administrator, Team OUYA
    That said, the ODK is the recommended way to setup your input because in the long run input will come from Java which is linked with user profiles and other hardware specific goodies and optimizations.

    And we mirrored the Unity input API as well with an added player parameter.
    ~Tim Graupmann
    OUYA Inc | Android Developer
    Skype: tgraupmann_prey

    http://github.com/ouya/docs
    http://github.com/ouya/ouya-sdk-examples

    Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]

    Use caution when setting [persistent wireless mode].
  • SetsukiSetsuki Posts: 13Member
    You mean, using the event based input tool, instead of the OuyaInputManager ?
    HeroTown : free 2.5D 4-player Beat'em up for OUYA
  • tgraupmanntgraupmann Posts: 2,869Administrator, Team OUYA
    I mean the preferred way to use input is documented in the FAQ section using OuyaInputManager. You use the event handler for event driven input. And you use OuyaInputManager for state driven input.

    There are various scenarios where depending on gameplay you want a combination of event and state based.

    http://forums.ouya.tv/discussion/309/frequently-asqued-questions-questions-i-had-and-solved-in-this-forum/p1
    ~Tim Graupmann
    OUYA Inc | Android Developer
    Skype: tgraupmann_prey

    http://github.com/ouya/docs
    http://github.com/ouya/ouya-sdk-examples

    Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]

    Use caution when setting [persistent wireless mode].
  • DreamwriterDreamwriter Posts: 768Member
    And we mirrored the Unity input API as well with an added player parameter.
    Actually, it's not quite mirrored correctly, which is the point of Setsuki's code - in Unity's input, GetKeyDown only registers true the very first Update that a button was pressed, but in the Unity ODK GetKeyDown registers true every single Update that the button is down - in other words, it acts like Unity's GetKey. I too hacked in my own changes to the Unity ODK for my project to replicate that functionality.
  • goodhustlegoodhustle Posts: 144Member
    Actually, it's not quite mirrored correctly, which is the point of Setsuki's code - in Unity's input, GetKeyDown only registers true the very first Update that a button was pressed, but in the Unity ODK GetKeyDown registers true every single Update that the button is down - in other words, it acts like Unity's GetKey. I too hacked in my own changes to the Unity ODK for my project to replicate that functionality.

    Unfortunately, many of us have been keeping our own hacked input listeners since we got our devkits, just to make up for the fact that it's not a drop-in replacement for Unity Input. I brought this this up several times but eventually came to the conclusion that this is just a philosophy difference and I need to write my own code, so I did. My goal was to make porting as seamless and easy as humanly possible with a complete mirror of the Unity Input API's 3 different use styles (example of some expected usage here).

    It's important to note that Setsuki's code doesn't fully implement the Unity Input API and requires that you rewrite the input configuration to use OuyaSDK KeyEnums to GetButton, which goes against the Unity Input philosophy of identifying virtual axes/buttons via strings. 

    I went out of my way to implement GetKey, anyKey/anyKeyDown, multiple controllers with convenience all-joystick KeyCodes, etc. because I really wanted to get an exact API mirror for my own existing large projects. A real mirror must implement GetAxis(string), GetButton(string), GetKey(KeyCode), GetKey(string), anyKey(Down), with all the Up/Down variants *exactly*. It's actually a lot of work, and it's taken me a really long time to get to a point where it's all working as I wanted it to in multiple projects.

    FYI, I also agree about letting input flow from the ODK in java. I directly use the OuyaController class to collect data on the java side and expose it to Unity via JNI bridge for performance, and also wrote in calling into ODK for IAP/etc functions, which wasn't actually all that hard once I learned how to do JNI calls.
    Beast Boxing Turbo - OUYA Launch Title!
  • TomPendergrassTomPendergrass Posts: 14Member
    I second Dreamwriter's statement. I'm trying to get my menus working, and I find myself writing an excessive amount of extra code so that menu selection only moves one 'slot' when DPAD_DOWN is true, since it registers true for every frame it's enabled. I'm using a generic USB controller that the OuyaInputManager doesn't recognize even after following Marco's video tutorials; I am using Xpadder to output keyboard input with my controller, that then calls HandleButtonEvents(). It really is a nightmare.
  • tgraupmanntgraupmann Posts: 2,869Administrator, Team OUYA
    It sounds like you just want to use the event handler in that case. I added a Starter Kit example in 0.0.6.3. Did you see the update? Sign up for update notifications and you'll get the starter kit example.
    ~Tim Graupmann
    OUYA Inc | Android Developer
    Skype: tgraupmann_prey

    http://github.com/ouya/docs
    http://github.com/ouya/ouya-sdk-examples

    Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]

    Use caution when setting [persistent wireless mode].
  • DreamwriterDreamwriter Posts: 768Member
    edited March 2013
    But, the event handler is nothing like how Unity handles input.  It just seems strange that the state-based system doesn't act like Unity's input handler either, so people who have a lot of experience working with Unity's input system can't use the ODK without learning a whole new input system or going to a lot of effort, when it seems like the state-based system is designed to mirror Unity's system.
    Post edited by Dreamwriter on
  • tgraupmanntgraupmann Posts: 2,869Administrator, Team OUYA
    Check out 0.0.6.3 as I've redone the documentation around the input system. There's a pdf, and I rewrote the section on input.
    ~Tim Graupmann
    OUYA Inc | Android Developer
    Skype: tgraupmann_prey

    http://github.com/ouya/docs
    http://github.com/ouya/ouya-sdk-examples

    Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]

    Use caution when setting [persistent wireless mode].
  • DreamwriterDreamwriter Posts: 768Member
    edited March 2013

    I just checked it out, I like the new documention.  But 0.0.6.3 still has this exact same issue, and the documentation doesn't mention it, though the documentation does state that the state-based system is supposed to be like Unity's input functions, but with the additional player code.

    The problem is, in OuyaInputManager the function GetButtonDown(string inputName, OuyaSDK.OuyaPlayer player) just calls GetButton and returns the results.  But that's not how Unity's GetKeyDown or GetButtonDown functions work - here's the Unity documentation for GetButtonDown:


    Returns true during the frame the user pressed down the virtual button identified by buttonName.

    You need to call this function from the Update function, since the state gets reset each frame. It will not return true until the user has released the key and pressed it again.

    Use this only when implementing action like events IE: shooting a weapon.

    Post edited by Dreamwriter on
  • Miniboss1232Miniboss1232 Posts: 45Member
    It's simple: GetButtonDown in ODK does not work like GetButtonDown in Unity. Until they do, I will NOT use the ODK Unity package. Ever.

  • tgraupmanntgraupmann Posts: 2,869Administrator, Team OUYA
    Right we are different. I should say we have a similar API interface. We can achieve the same functionality using an event handler. And we aren't limited to working in the Update. We can work from OnGUI, Update, or FixedUpdate when you want to check the controller state. It will return true the entire time the button is pressed. If you want a single action, you use the input handler event.
    ~Tim Graupmann
    OUYA Inc | Android Developer
    Skype: tgraupmann_prey

    http://github.com/ouya/docs
    http://github.com/ouya/ouya-sdk-examples

    Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]

    Use caution when setting [persistent wireless mode].
  • DreamwriterDreamwriter Posts: 768Member
    You should change the name of the GetButtonDown function in there then, or remove it altogether, because as it is that'll just confuse people and make people try to take their existing Unity project and change the input calls to UnityInputManager calls, and that's just not going to work since the functionality is different.
  • tgraupmanntgraupmann Posts: 2,869Administrator, Team OUYA
    We could something where the JNI update comes in in the middle of an update (async) and then it will only be true on the next update frame.
    ~Tim Graupmann
    OUYA Inc | Android Developer
    Skype: tgraupmann_prey

    http://github.com/ouya/docs
    http://github.com/ouya/ouya-sdk-examples

    Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]

    Use caution when setting [persistent wireless mode].
  • HashbangGamesHashbangGames Posts: 96Member
    So first off,  Id like to start by saying I feel a great amount of disrespect from this thread.  Tim and I both have been working very hard to get this stuff in place and in a short amount of time.  I feel that there are a bunch of very supportive people here in this thread and then some that are just outright not respecting the process of development.  

    I acknowledge that we have a problem with the ODK Unity Package and that it is not mirroring the Unity functionality exactly.  And like goodhustle has previously stated that it is a lot of work to put an exact mirror of Unity Input functionality.   

    Our purpose was to provide the community with a method in which you can interact with the controllers to get your games up and running and working in a short amount of time.  We have provided this and if used as we have suggested it does work and it works correctly.   Is it the "Best" way?  I cannot say.  Is it exactly the same as the way that Unity handles input? Certainly not.   We are working hard on this and we intend to attempt to get the functionality as close to it as possible.  This however, will take some time and patients on your part to wait for us to implement the features that your requesting.  There is a right channel of requesting features which we have provided  for you at our customer portal.  

    Meanwhile, there are a lot of good solutions out there if you don't feel like using the ODK until we get the kinks worked out,  goodhustle has one example that works with polling in the update.   Or you can use the ODK, with our event driven model, which is just as effective.   

    There is really no need for arguments, and certainly no need for statements like "I'm not going to use the ODK until it's fixed".   It's disrespectful to the process and we have people that are volunteering their time and efforts for you to have a solid ODK and Unity integration.   I know for a fact that Tim and myself have gotten many projects successfully working.   

    I am asking that you all just be a bit patient with us while we work out the kinks of the Unity Plugin, and we will continue to provide updates.    I am also asking that you do not ask or suggest to people that they do not use our ODK or avoid using the ODK,  Because currently it is the quickest and easiest way to get the controllers working.    The ODK currently is stable, and has cross platform and editor support.  If you are having problems with anything,  Tim and I both are always willing to help you find a working solution to your problems.  You can ping either of us directly and we are most glad to help you.

    Thanks,
    Marco G. Williams
    Hashbang Games


    Marco Williams
    Hashbang Games

    Gravi is available on the OUYA look for it in the store!

    Steam Greenlight Vote yes on Gravi
    Purchase our Gravi on Desura
    Desura Digital Distribution
  • Killa_MaakiKilla_Maaki Posts: 504Member
    edited March 2013
    Personally I would just write a wrapper around the ODK's input manager, storing button states for the last and current frames. GetButton would of course just return whether the button is currently pressed. GetButtonDown returns whether the button was NOT pressed last frame but IS pressed this frame. GetButtonUp returns whether the button WAS pressed the last frame, but is NOT pressed this frame.
    I've done a similar thing in XNA for their GamepadState API, doesn't sound too hard to do with ODK either.

    EDIT: And personally, saying you're not going to use the ODK until the above quirk is fixed is just plain lazy, especially when the fix is so simple to do on your own.
    Post edited by Killa_Maaki on
    You didn't remember the plot of the Doctor Who movie because there was none; Just a bunch of plot holes strung together.
  • SetsukiSetsuki Posts: 13Member
    There is a reason I made this thread, and this script, simple to use and fast to implement : because it'll be also simple to remove.
    I wanted to try the game on OUYA but my controls didn't work. I made them work because I couldn't wait to see if the game was working.
    In no way I consider tgraupmann's or your work bad or too slow. You are porting a whole SDK to a specific engine, and in a short amount of time. I realize that "the controls aren't working EXACTLY like Unity does" isn't the most important problem, mainly when it can be changed as I did.

    I respect your work and thank you for all you did for Unity users. In no way I wanted this script to be seen as a "better Unity ODK", just a temporary fix for people like me who already programmed their controls.
    HeroTown : free 2.5D 4-player Beat'em up for OUYA
  • HashbangGamesHashbangGames Posts: 96Member
    @Setsuki  my comment wasn't geared towards your initial post.  We are actually looking how you did some of your code in that package to incorporate it.  I love that you posted this solution.  

    Thanks,
    Marco G. Williams
    Hashbang Games

    Check out our game Gravi and vote for us on greenlight
    Marco Williams
    Hashbang Games

    Gravi is available on the OUYA look for it in the store!

    Steam Greenlight Vote yes on Gravi
    Purchase our Gravi on Desura
    Desura Digital Distribution
  • Miniboss1232Miniboss1232 Posts: 45Member
    I'd like to apologize for my behavior earlier in the thread. It was brought about by too much crunch time, not enough sleep, and the fact that the GetButtonDown thing is a pet peeve of mine. That doesn't excuse my behavior, but I felt I needed to at least give an explanation.

    Again, I apologize. I know you guys are doing your best to make the best plugin possible.

    On the constructive side of things, we actually have been using @goodhustle's solution for quite a while now, and basically haven't had a problem with it. We have a situation where we have a multiplatform game, and we can't use the polling solution (unless we wanted to rewrite Unity's input handling for all supported platforms). And in a pinch, his worked. I'm not sure if you can glean anything from it, but I thought I would offer that bit of feedback.

  • skytigerskytiger Posts: 14Member
    edited June 2013
    People are getting upset because you are not admitting a simple mistake
    Post edited by skytiger on
  • tgraupmanntgraupmann Posts: 2,869Administrator, Team OUYA
    edited June 2013
    Ah this is such and old thread.

    Here is the best example of low-latency input.

    Unity - Example - ShowUnityInput - Part 1
    Post edited by tgraupmann on
    ~Tim Graupmann
    OUYA Inc | Android Developer
    Skype: tgraupmann_prey

    http://github.com/ouya/docs
    http://github.com/ouya/ouya-sdk-examples

    Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]

    Use caution when setting [persistent wireless mode].
  • skytigerskytiger Posts: 14Member
    Time, after finally getting your examples working and understanding your code the best advice I can give to others is:

    DO NOT USE this code - use the existing Unity Input class

    this Ouya SDK controller code is a productivity killer and a productivity timebomb
    and is frankly ridiculous and you DON'T NEED IT
  • tgraupmanntgraupmann Posts: 2,869Administrator, Team OUYA
    edited June 2013
    The best part is the OuyaExampleCommon.cs which allows you to detect based on the controller name which button and axis mappings to use.

    Without it, you'd have to write the code yourself if you expect to work with multiple controller types on multiple platforms.
    Post edited by tgraupmann on
    ~Tim Graupmann
    OUYA Inc | Android Developer
    Skype: tgraupmann_prey

    http://github.com/ouya/docs
    http://github.com/ouya/ouya-sdk-examples

    Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]

    Use caution when setting [persistent wireless mode].
  • SetsukiSetsuki Posts: 13Member
    edited June 2013
    I was getting angry last weekend when I realized the OuyaInputManager created a lot of latency on our buttonmashing multiplayer game. It could provoke up to 10 seconds latency (which was as fun as annoying).
    I made a non graphic mini-game where the players must push the buttons as fast as they can, the first one to get to 100 wins, and it starts over.
    I still have this project, and have been using it to try the diverses input solutions provided with the unity ODK.
    As tgraupmann said, the way used in OuyaExampleCommon is the right one, using unity's Input like OuyaExampleCommon is now the right way to do it.

    But the system button doesn't seem to work...

    P.S. : Would an admin be kind enough and edit the original post to warn people that this isn't a good solution anymore ?
    Post edited by Setsuki on
    HeroTown : free 2.5D 4-player Beat'em up for OUYA
  • derkoiderkoi Posts: 20Member
    So what do I do with OuyaExampleCommon? Put it on my player game object?
  • SetsukiSetsuki Posts: 13Member
    edited June 2013
    OuyaExampleCommon isn't a MonoBehaviour so it can't be attached. But it is static so you can use it whenever you want, just use it as another input system.


    For example, if you want to detect a button press on O on the second controller, use

    if ( OuyaExampleCommon.GetButton(OuyaSDK.OuyaPlayer.player2,OuyaSDK.KeyEnum.BUTTON_O) )
    {
        Application.PlayAwesomeGame();
    }

    The OuyaExampleCommon will automatically create the string used by unity to identify this precise button on this precise controller, and will return you what Input.GetButton return.

    since it uses Unity's Input, you have to change your inputmanager by the one given with the unitypackage (3.x or 4.x depending on your version of Unity). this was the major problem for me, so I simply have two InputManager.asset and change to whichever I need to buid.

    last, but not least, you have to call OuyaExampleCommon.UpdateJoysticks() for this to work. I don't think I need to explain what this function does... Personally, I call it in OuyaGameObject every FixedUpdate (our game's controls are physics based, and it's a fast-paced game, so we need quick reaction for a lot of input).
    Post edited by Setsuki on
    HeroTown : free 2.5D 4-player Beat'em up for OUYA
  • tgraupmanntgraupmann Posts: 2,869Administrator, Team OUYA
    edited June 2013
    To get the system button you have to subscribe with a broadcast receiver to watch for the MENU-APPEARING Intent; which is already there.

    You'll see on the examples there's a callback listener:

    public class YourClass : MonoBehaviour,
        OuyaSDK.IMenuAppearingListener
    {
        void Awake()
        {
            OuyaSDK.registerMenuAppearingListener(this);
        }
        void OnDestroy()
        {
            OuyaSDK.unregisterMenuAppearingListener(this);
        }

        public void OuyaMenuAppearing()
        {
            Debug.Log(System.Reflection.MethodBase.GetCurrentMethod().ToString());
        }
    }


    And that will catch the system button.


    I can't edit posts older than a month.


    OuyaExampleCommon.UpdateJoysticks() 

    is just a timer to call Input.getJoystickNames() every 3 seconds. I figured why get the Joystick names 100 times a second. That way it doesn't eat any performance accessing the cached Joystick names. And after 3 seconds you can detect a disconnected Joystick and that's fast enough.
    Post edited by tgraupmann on
    ~Tim Graupmann
    OUYA Inc | Android Developer
    Skype: tgraupmann_prey

    http://github.com/ouya/docs
    http://github.com/ouya/ouya-sdk-examples

    Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]

    Use caution when setting [persistent wireless mode].
  • EMcNeillEMcNeill Posts: 47Member
    Wow, OuyaExampleCommon.cs is hugely useful for me. I can't believe it will be this easy to support PS3 and MOGA controllers on OUYA!

    Tim, you might consider renaming the file in the future, or putting it in a different place. Without watching that video, I would've assumed it was some background utility file that was only relevant to the example scenes.
  • tgraupmanntgraupmann Posts: 2,869Administrator, Team OUYA
    Well kinda. My  long term plans (and in my experimental stuff) I've moved OuyaExampleCommon.cs into OuyaInputManager.cs to replace the legacy stuff.
    ~Tim Graupmann
    OUYA Inc | Android Developer
    Skype: tgraupmann_prey

    http://github.com/ouya/docs
    http://github.com/ouya/ouya-sdk-examples

    Check out the latest docs for your game engine: [setup] [adobe air] [android] [clickteam fusion] [construct 2] [corona] [libGDX] [game maker] [html5] [marmalade] [monogame] [unity] [unreal]

    Use caution when setting [persistent wireless mode].
Sign In or Register to comment.