Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Steam hijacking controller input #380

Open
Arcalise08 opened this issue Oct 2, 2020 · 74 comments
Open

Steam hijacking controller input #380

Arcalise08 opened this issue Oct 2, 2020 · 74 comments

Comments

@Arcalise08
Copy link

Not sure if this intended or not. But upon initializing steamworks. My xbox one controller is no longer recognized within unity. No inputs will reach it until i close steam. I can get the game working by building it, opening the overlay and going to controller configurations then selecting to apply the generic gamepad. It will then work as intended. But within the editor nothing i do seems to work.

@streaman
Copy link

streaman commented Oct 7, 2020

Same exact problem here. This is definitely BLOCKING and should be assigned and fixed asap.

Happens with Unity's New Input System.

Easy way to check the issue is running this code in an Update() callback:

    for (int i = 0; i < Gamepad.current.allControls.Count; i++) {
      InputControl ic = Gamepad.current.allControls[i];
      if (typeof(float).IsAssignableFrom(ic.valueType)) {
        float v = (float) ic.ReadValueAsObject();
        if (v > 0) {
          Debug.LogError("  [" + i + "]: " + ic.shortDisplayName + " = " + v);
        }
      }
    }

Before initializing Steamworks, this code will output a line to Unity console for every button or trigger pressed.
After initializing Steamworks, all inputs will be 0 and nothing will be output to Unity console anymore.
Only way to resume normal gamepad operation is quit&restart Unity and avoid initializing Steamworks.

@Arcalise08
Copy link
Author

Same exact problem here. This is definitely BLOCKING and should be assigned and fixed asap.

Happens with both Unity's Old and New Input System.

Easy way to check the issue is running this code in an Update() callback:

    for (int i = 0; i < Gamepad.current.allControls.Count; i++) {
      InputControl ic = Gamepad.current.allControls[i];
      if (typeof(float).IsAssignableFrom(ic.valueType)) {
        float v = (float) ic.ReadValueAsObject();
        if (v > 0) {
          Debug.LogError("  [" + i + "]: " + ic.shortDisplayName + " = " + v);
        }
      }
    }

Before initializing Steamworks, this code will output a line to Unity console for every button or trigger pressed.
After initializing Steamworks, all inputs will be 0 and nothing will be output to Unity console anymore.
Only way to resume normal gamepad operation is quit&restart Unity and avoid initializing Steamworks.

I've been messing around with it personally, And i dont actually think this is a steamworks.net issue. I think that engaging steam redirects input. Its just a fundamental compatibility issue with steam and unity. From my test, Actually building to steam servers and playing works just fine. Its just the quirk of testing controller inputs with steam initialized which is difficult. If anyone has a better solution, Or maybe i'm completely wrong about it being a steam issue and not a steamworks. Please let us know!

@streaman
Copy link

streaman commented Oct 8, 2020

I agree this can be a Steamworks SDK issue, and not the .NET wrapper.
It could also be a Unity bug (I filed a bug report with Unity too).
Hope someone can tell us what's happening.

@Arcalise08
Copy link
Author

I agree this can be a Steamworks SDK issue, and not the .NET wrapper.
It could also be a Unity bug (I filed a bug report with Unity too).
Hope someone can tell us what's happening.

I've mostly fixed this issue. I'm not entirely sure how i did it. Try adding unity, the actual executable(not the hub) to steam and start unity through steam.

Again i do believe this to be a pretty bad bug. But at this point i have no idea how to replicate it nor do i want to.

@streaman
Copy link

streaman commented Oct 8, 2020

Thanks for the feedback. I am afraid to use your workaround, as I want to be sure the game works regardless of the way the executable is started. By the way, a standalone build has the same issue, so it's not only the editor.

I double-checked the Old Input System, and it now seems to be working for me.
For example, I can read the controller buttons using:

Input.GetKey(KeyCode.JoystickButton0)

It now looks more and more like a Unity bug to me. And it's so disappointing to realize that the New Input System (v1.0.0) is not being tested against one of the most obvious use cases (Steam games).

@Arcalise08
Copy link
Author

Thanks for the feedback. I am afraid to use your workaround, as I want to be sure the game works regardless of the way the
executable is started. By the way, a standalone build has the same issue, so it's not only the editor.

Thats a little confusing. If your game is a steam game. You want it to launch with steam. When its built and distributed through steam. Steamworks will automatically close and relaunch your game through steam if it was started without steam. It doesnt do this if you have your app_id in the root folder such as when your developing. But otherwise it does. If its started without steam you wont be able to use steam features.

It now looks more and more like a Unity bug to me. And it's so disappointing to realize that the New Input System (v1.0.0) is > not being tested against one of the most obvious use cases (Steam games).

When i started targeting steam as my release partner i was absolutely shocked that steam doesnt officially support unity. Make no mistake though. This is on steams end, not unitys. Since steam is the distributor of the games, They are the ones whose responsibility it is to release plugins that support their distribution platform. Its my guess that they dont support unity because unity targets C# programmers while steamworks uses C++. Because they do officially support unreal engine.

Until they officially support unity, we have to deal with annoyances like this.

@rlabrecque
Copy link
Owner

https://steamcommunity.com/groups/SteamClientBeta/announcements/detail/2936869850608535686

Improved support for games using Windows raw input APIs
Unity games using the Rewired plugin should upgrade to the latest release, version 1.1.36.1.

Did this Steam update improve things at all?

@streaman
Copy link

streaman commented Oct 27, 2020 via email

@timkeo
Copy link

timkeo commented Nov 25, 2020

Hey,

I'm a Unity software engineer and currently investigating this issue (Unity bug link).

From my investigation, the problem seems to be Steam itself is (for lack of a better word) "hijacking" XInput. Unity's internal calls to XInputGetState() fail with ERROR_DEVICE_NOT_CONNECTED once the Steam API is initialized. I suspect it's actually the Steam Overlay that may be causing the problem as I found we stop getting input once this DLL is loaded.

'Unity.exe' (Win32): Loaded 'C:\Program Files (x86)\Steam\GameOverlayRenderer64.dll'.

Since it's the Windows API itself that's failing, I don't think there's anything Unity nor Steamworks can do about it, However, I'd like to find a confirmed work around which I can paste into the bugs resolution notes.

@Arcalise08
Copy link
Author

Arcalise08 commented Nov 25, 2020

Hey,

I'm a Unity software engineer and currently investigating this issue (Unity bug link).

From my investigation, the problem seems to be Steam itself is (for lack of a better word) "hijacking" XInput. Unity's internal calls to XInputGetState() fail with ERROR_DEVICE_NOT_CONNECTED once the Steam API is initialized. I suspect it's actually the Steam Overlay that may be causing the problem as I found we stop getting input once this DLL is loaded.

'Unity.exe' (Win32): Loaded 'C:\Program Files (x86)\Steam\GameOverlayRenderer64.dll'.

Since it's the Windows API itself that's failing, I don't think there's anything Unity nor Steamworks can do about it, However, I'd like to find a confirmed work around which I can paste into the bugs resolution notes.

From my test the inputs arent reaching unity and its not unity's fault for that. I found two ways of getting it working. You have to be able to open the Overlay in the editor. If you can do that, You can set the gamepad within the overlay and then it will work normally.

What is really strange is when you do get that overlay open. all you need to do is set the gamepad, The default gamepad works just fine but you still have to set it to something else. after you set it to something else you can then set it right back to default and it works. That means its default gamepad profile works just fine. Its just a matter of resetting it every time the game is started

I've mostly stopped messing with steam for the time being. But my trail of thinking was, If we programmatically unset the default controller profile then set it right back, It might work without needing the overlay.

You can also add unity to Steam as an external program. It will inject the overlay into unity and that works.. sometimes.. Its not dependable at all. so I wouldn't suggest that being a workaround.

@timkeo
Copy link

timkeo commented Nov 26, 2020

Thank you for the reply, I'll add this information to the Unity bug.

As I've dug deeper into this problem I've discovered...Steam iterally is hijacking XInput! When the Steam Overlay module is loaded, it actually modifies the XInput API call to redirect it to it's own code; basically what a virus would do.

From Unity we call into XInputGetState() which looks like this in the disassembly:

           errorCode = s_XInputGetStateFn(userIndex, &state);
00007FF78DDFAD4C  mov         rax,qword ptr [win::XInputDevice::s_XInputGetStateFn (07FF79E320148h)]  
00007FF78DDFAD53  mov         qword ptr [rsp+88h],rax  
00007FF78DDFAD5B  lea         rdx,[state]  
00007FF78DDFAD60  mov         rax,qword ptr [this]  
00007FF78DDFAD68  mov         ecx,dword ptr [rax+8]  
00007FF78DDFAD6B  call        qword ptr [rsp+88h]  => 00007FFF40B816F0 (XInput DLL address)
...

From here the disassembly (should) look like this:

XInputGetState:
00007FFF40B816F0  mov         qword ptr [rsp+8],rbx  
00007FFF40B816F5  push        rsi  
00007FFF40B816F6  push        rdi  
00007FFF40B816F7  push        r14  
00007FFF40B816F9  sub         rsp,30h
...  

Now, start Steamworks in the Editor and break into XInputGetState again:

XInputGetState:
00007FFF40B816F0  jmp         00007FFF62590E4A  
00007FFF40B816F5  push        rsi  
00007FFF40B816F6  push        rdi  
00007FFF40B816F7  push        r14  
00007FFF40B816F9  sub         rsp,30h  
...

Notice the mov instruction from before has been replaced by a jmp

That jump takes us to some other place in memory where we encounter these 2 instructions:

00007FFF62590E45  jmp         XInputGetState+5h (07FFF40B816F5h)  
00007FFF62590E4A  jmp         00007FFEFA7F0790  

The 1st jmp instruction, which we do not execute, takes us back to XInputGetState, and continues to execute the API normally.
The 2nd jmp instruction, which we end up calling, takes us here:

00007FFEFA7F0790  mov         r8,rdx  
00007FFEFA7F0793  xor         r9d,r9d  
00007FFEFA7F0796  mov         edx,ecx  
00007FFEFA7F0798  mov         rcx,qword ptr [7FFEFA8EE1D8h]  
00007FFEFA7F079F  jmp         00007FFEFA7F07D0  
...

Using the module info, this instruction address occurs within Steam's GameOverlay:
(Module) GameOverlayRenderer64.dll (Addr Range) 00007FFEFA730000-00007FFEFA911000

I'm unsure exactly what this Steam function is doing but it ultimately dumps out the error code for ERROR_DEVICE_NOT_CONNECTED before returning.

So basically Steam is deliberately overriding XInput to block input for other callers (in the same process) once the Overlay DLL has been loaded unless you do something special.

Based on the comment above, my guess is Steam redirects the XInput API call depending on the state of things. If you do the "right" thing it injects the jmp instruction to point to the 1st address (00007FFF62590E45 in this case) and everything works fine, but if you don't do the magic thingy you get the 2nd address (00007FFF62590E4A, what we're currently seeing) and Input no longer works.

So anyway, not much we can do unless we add our own hack to counteract Steam.

@rlabrecque
Copy link
Owner

rlabrecque commented Nov 26, 2020

Hey @timkeo, thanks for the confirmation.

Could you try out your repro case with the latest beta of steam too?

This seems to be in very active development the last few weeks again.

https://steamcommunity.com/groups/SteamClientBeta/announcements/detail/2896339990517078189

Improved support for games that use raw input for controllers

https://steamcommunity.com/groups/SteamClientBeta/announcements/detail/2896340624042995521

Disabled experimental support for more than 4 Xbox controllers pending further testing

cc: @slouken

@slouken
Copy link

slouken commented Nov 26, 2020

Hi guys, I'm one of the engineers at Valve who works on input. @timkeo, nice to meet you!

The problem is that when you initialize the Steamworks API, Steam probably doesn't know what kind of input you need. If you don't have an appID, it's giving you the desktop configuration, which defaults to disabling controller input or mapping it to keyboard and mouse. If you're using steam_appid.txt to specify your appID and have 480 in there, you're telling Steam that your application is SpaceWar, which actually has Steam Input mappings and controller input is redirected to Steam Input instead of XInput.

If you have a real Steam game, then you should make sure you're specifying that appID in steam_appid.txt, and then go to the Steam Input settings on the partner page for your app and select the "Generic Gamepad" template.

If you're just doing prototyping and don't have a Steam appID yet, you can put 1456390 in steam_appid.txt, which is an appID set up for game controller testing.

Cheers!

@timkeo
Copy link

timkeo commented Nov 30, 2020

Thanks @slouken for the response and detailed explanation! I haven't actually developed on the Steam platform before and still learning how things work.

I'll share this information on the Unity forums so others will have better chance of seeing it.

@rlabrecque
Copy link
Owner

Steamworks.NET does seem to have some role to play here then. As we do set the default AppId to 480 for a good out of box experience.

I'm hesitant to just switch right to 1456390 as the default though as a lot of the examples we have utilize content and permissions that 480 has, such as Lobby and Workshop which 1456390 may not have enabled.

Better documentation around this and pushing people to use their own AppId sooner may help.

@slouken
Copy link

slouken commented Nov 30, 2020

If you test it and find things that are missing, let me know and I can enable them.

@slouken
Copy link

slouken commented Nov 30, 2020

@timkeo
You're welcome!
We've been improving our raw input controller support so it works better with Unity. If you have any troubles with the current Steam beta client, please let me know, and I'll take a look.

@mle-ii
Copy link

mle-ii commented May 24, 2021

@slouken @rlabrecque Curious if there is a fix, workaround or solution here?

I have been trying to figure out an issue with a game that I'm playing where it seems that the controller input gets into a broken state either when it starts the game outside of steam or if at any time during play the controller disconnects and reconnects, or if the player connects the controller after the game starts. This is with the Unity Legacy Input System if it matters. The game where I'm hitting this issue is Vaheim. I've helped them figure out fixes to other controller issues with Steam/Unity but this one has me stuck. :(

I am also testing with an Xbox One Wireless Bluetooth Controller if that matters, but I'm pretty sure I've repro'd this with a wired 360 controller, though I'll follow up if need be though pretty sure that's not a variable here. And it doesn't solve the issue for those who, like me, use that type of controller.

I wrote a simple unity app that repros the behavior only when SteamWorks.NET is being used. Even starting my app inside or outside Steam without SteamWorks.NET as part of the test app, it does not repro the issue. I've used both the default 480 and 1456390 app ID and they both repro the issues I'm seeing.

The side effect of this is that the Left and Right Trigger end up getting swapped. Normally the Left Trigger should return -1 to 0 and the Right Trigger should return 0 to 1. But when SteamWorks.NET is being used the reverse is true. And also in some situations Steam ends up telling Unity that there are two different controllers connected. It seems like when Steam starts up it uses a default of an Xbox 360 controller, but if you disconnect and reconnect it sees an Xbox 360 controller connected and an Xbox One controller. But it's the same controller. And I can see it sending the swapped data for the trigger and what it should actually be. So in the game I'm playing if you pull the Left Trigger down the game registers both the Left and Right Trigger being pulled down.

It also doesn't seem to have Axis 9 and 10 registered which are the Left and Right Trigger, but separated. So with Axis 9 you get 0 to 1 for LT and for Axis 10 you get 0 to 1 for RT.

Also are there examples somewhere that I can look at for how to use SteamWorks.NET with controller input? That might help me narrow down the issue more.

Or any other things to test out here?

@mle-ii
Copy link

mle-ii commented Jun 3, 2021

@timkeo Not sure you've looked at this any more since you last mentioned finding what was going on, but do you have any ideas on what could be done here? This issue causes bugs in games that use this library with unity when using controllers. Especially when you don't have the controller plugged in before the game starts or the controller disconnects and you reconnect it. You have to restart the game and sometimes steam to get it back to working. :(

@slouken @rlabrecque I've tried a few different things like stopping SteamInput to see if it'd release messing with XInput, but didn't seem to work. I don't see any ways in the API to do anything else that might help remove what timkeo discovered it was doing, guessing that's deeper in the SteamWorks API than the csharp "shim" for the SteamWorks unmanaged library.

I can try more things out but at a loss for what to do here. I am not a game developer, though learning, so I don't have access to the SteamWorks discussion group on the Steam forums to ask there or report the issue.

Can someone see if this can be fixed at a lower level in Steam? Even just unity + steam alone without this library seems to have issues where when you first start up the game with the controller connected it reports a Xbox 360 controller when it's really an Xbox One controller, and if you disconnect and reconnect the controller by say removing and putting the battery back in it then Unity seems to think that there are both an Xbox 360 controller and an Xbox One controller connected. :/

@timkeo
Copy link

timkeo commented Jun 3, 2021

Unfortunately there's nothing Unity can do about this problem either.

Since Steam is deliberately violating the API contract with XInput, there's no way to prevent this in the XInput implementation, and since XInput is a Microsoft library, we can't change the XInput API to prevent the hack. The only possible work-around is to hack Steam's hack and change the machine code back. Unity absolutely cannot make this kind of change.

This is something Valve will have to fix.

@slouken
Copy link

slouken commented Jun 3, 2021

I can take a look at this, can you give me repro steps for a Unity noob? :)

@mle-ii
Copy link

mle-ii commented Jun 3, 2021

Unfortunately there's nothing Unity can do about this problem either.

Since Steam is deliberately violating the API contract with XInput, there's no way to prevent this in the XInput implementation, and since XInput is a Microsoft library, we can't change the XInput API to prevent the hack. The only possible work-around is to hack Steam's hack and change the machine code back. Unity absolutely cannot make this kind of change.

This is something Valve will have to fix.

Figured as much, was hoping to see if I could figure out something in the API wrapper but found nothing.

I can take a look at this, can you give me repro steps for a Unity noob? :)

For sure! Gotta work for about 8 or so hours but after work I'll give you a simple steps for creating a simple project and some project code to repro a few of the things I've mentioned. Thank you!

Thank you both!

@mle-ii
Copy link

mle-ii commented Jun 4, 2021

@slouken Ok, I redid everything and put it here and made it pretty much just a project you follow the log instead of all the UI.
https://github.com/mle-ii/ControllerSteamWorksNet

Readme with how to build and repro.
Unity package if you want to build it on your own.
Along with the 2 most important files if you want to created it manually from scratch.

Also a zip file that contains the version already built.

@mle-ii
Copy link

mle-ii commented Jun 9, 2021

@slouken A couple of comments on things. If you want the version of the "game" repro that shows on screen things rather than just in the logs let me know. On reason I created the console log only version was to make it easer for you to build instead of using the binaries I built myself. And I see in my repro steps I left comments about the text box, I'll fix that.

Finally, if you use a wired Xbox 360 controller it does the same things, you just have to unplug it and plug it back in to simulate the disconnect. It even seems that Unity is being told there are 2 Xbox 360 controllers connected, when it's only that one connected.

Oh and it still repros in the latest version of Steam, don't see a newer version of this Steamworks.NET library, but then I do think it's at a lower level than this library now.

@slouken
Copy link

slouken commented Jun 9, 2021

On-screen feedback would be useful. I noticed that this build still uses appid 480, which is guaranteed not to work properly.

@mle-ii
Copy link

mle-ii commented Jun 9, 2021

I'll upload that version, describing how to build it for someone who didn't know unity was... hard. So I gave it up.

It doesn't matter what id is used, I tried both they behave the same. I thought I had the copy for id 1456390 but I must have not put that in my build. It's easy enough to add though.

@mle-ii
Copy link

mle-ii commented Jun 9, 2021

Actually, it seems I might need to rebuild it as it's now crashing after the update I just installed for steam today. :/

@mle-ii
Copy link

mle-ii commented Jun 9, 2021

@slouken Huh, well it seems steam changed a behavior, the app works but only if run through steam now. Running outside of steam it crashes unless I run it from the Unity Editor. Works in the unity editor I just cannot run it by double clicking it in Explorer.

Here's the repro that logs on screen, it has the app id I believe that was mentioned was needed, that same file can be added to the other one as well, but regardless it behaves in the same way.
https://github.com/mle-ii/ControllerSteamWorksNet/blob/main/OnScreenDisplayControllerSteamWorksNetMinimalRepro.zip

@slouken
Copy link

slouken commented Jun 9, 2021

Can you add me as a Steam friend so we can work on this interactively? My username is slouken

@mle-ii
Copy link

mle-ii commented Jun 10, 2021

These are the APIs I'm using in that repro:
https://docs.unity3d.com/2019.4/Documentation/ScriptReference/Input.GetAxis.html
https://docs.unity3d.com/2019.4/Documentation/ScriptReference/Input.GetJoystickNames.html

I (and the game I'm playing that has issues) is using the Legacy Input system.

@slouken
Copy link

slouken commented Dec 16, 2021

Can you guys check today's beta (dated December 16, 2021) and see if that's fixed?

@mle-ii
Copy link

mle-ii commented Dec 17, 2021

Can you guys check today's beta (dated December 16, 2021) and see if that's fixed?

I will tonight after work. Thank you for looking into this.

@mle-ii
Copy link

mle-ii commented Dec 17, 2021

Can you guys check today's beta (dated December 16, 2021) and see if that's fixed?

Sorry, same behavior in both beta and regular client, though they both seem to have the same update data.
https://store.steampowered.com/oldnews/?feed=steam_client
https://steamcommunity.com/groups/SteamClientBeta

I tried these 3 and none worked:

  1. Having the controller on before starting up Steam Client
  2. Connecting the controller after starting Steam Client
  3. Using big picture mode

Then starting Valheim (a unity game) up in all 3 of those scenarios. In all 3 the xbox controller is not seen.

To get the controller to be seen I have to turn off and back on the controller after I start Valheim.

I can try another game, but you are not able to reproduce the bug in the current version? I suppose it could be a new bug in the game I'm playing but it's behaving similarly to before. Though before it would see 2 different controllers when doing that.

@mle-ii
Copy link

mle-ii commented Dec 17, 2021

Using the test application I wrote before it behaves similarly to Valheim. I need to take out the batteries, plug them back in then hit the xbox button to get it to register that the the controller is there while the game is running.

@mle-ii
Copy link

mle-ii commented Dec 18, 2021

Let me know how I can help here. I want to help make controllers work better in Steam.

@Paliverse
Copy link

Hello, im using the new input system and trying to talk with the DualSense controller through HID within Unity, unless Playstation Configuration is disabled or Steam Input in Game Settings is disabled, unity is unable to talk with the controller via the HID method.

@diegoaraujo443
Copy link

@slouken It`s fixed now. Some seconds after the game starts the controller starts working normally. Thank you for the fix!

@dpuza
Copy link

dpuza commented Jul 12, 2022

From what I understand of the conclusion, the proposed solution is to: 1) use the real app ID, and 2) publish Generic Gamepad as the default configuration for the App.

I've ensured both of those things, but the controller is still not recognized. As soon as I add the SteamManager script, it breaks the controller support in my game. If I rip the SteamManager back out, it works fine again. Or, if I keep the SteamManager, but exit the Steam client, I get an error on SteamAPI_Init() but the controller works.

@slouken
Copy link

slouken commented Jul 12, 2022

Are you also launching your game from Steam?

@dpuza
Copy link

dpuza commented Jul 12, 2022

Are you also launching your game from Steam?

No, I mean when debugging in Unity.
Also, App ID 1456390 does not work either.

@dpuza
Copy link

dpuza commented Jul 12, 2022

For now, I've added this prior to SteamAPI.Init() in my SteamManager.cs. This seems to work to prevent Steamworks from being loaded while in the Unity Editor, and so the controller continues to work in the Unity Editor.

if (Application.isEditor) { return; }

@dpuza
Copy link

dpuza commented Jul 12, 2022

Also FWIW, the built application, with Steamworks.NET loaded and going through the RestartAppIfNecessary with my appID: the controller works (and Steam overlay works). As expected.
Same built application, with steam_appid.txt with my appID: controller does not work.
I see that if I delete the steam_appid.txt from my Unity project folder, it constantly gets recreated.

@slouken
Copy link

slouken commented Jul 12, 2022

So you're saying that if your built application has steam_appid.txt, the controller doesn't work, but if you remove that file it does?
Is it already published on Steam? If not, can you e-mail me at slouken@libsdl.org with a link to your build so I can try it out here?

@dpuza
Copy link

dpuza commented Jul 12, 2022

So you're saying that if your built application has steam_appid.txt, the controller doesn't work, but if you remove that file it does? Is it already published on Steam? If not, can you e-mail me at slouken@libsdl.org with a link to your build so I can try it out here?

That's correct. You should have received access to the debug build by email. It's not published on Steam yet.
It doesn't exactly surprise me, since RestartAppIfNecessary relaunches it with Steam injected as if you launched it from Steam. And if the steam_appid.txt file is found, it does not do this. As described here: https://steamworks.github.io/steammanager/

@slouken
Copy link

slouken commented Jul 12, 2022

Ah, okay, that makes sense. Yes, in order for controllers to work properly the game needs to be launched from Steam, or with Steam injected as though you had launched it from Steam.

@squido-kf
Copy link

Hi @slouken, I'm on a VR project using the unity OpenXR (With the new Input system with actions) and I got the same issue that is mentionned in this thread.

All is fine if I don't initiliaze with the SteamAPI.Init(), but if we initialize, all our Unity's actions always return 0 values for the controllers. The HMD work as expected in both case.

I tried to set the Steam Input setting to "Generic Gamepad", but I think this not make sence in my context.
Any recommandation to make it work with this kind of setup? (Considering we need to be cross platform with Meta Quest, so the OpenXR was appealing)

Thanks!

@slouken
Copy link

slouken commented Sep 9, 2022

Does it work if your game is launched from Steam directly?

@squido-kf
Copy link

I don't have a version of the game with the Steamworks.NET integrated yet on Steam (But the current one without the Steamworks works). I tested locally with the steam_appid.txt.
I guess I can try to upload a quick test build on a steam branch.

@squido-kf
Copy link

@slouken , I can confirm that works from Steam directly.

@petersvp
Copy link

Guys, I will add my 5 cents to this. Using old unity 2019 with the legacy input system and NO steam running, no appid and no steamworks. Unplugging and replugging the controller messed up its mappings, unity sees 2 controllers now.

Decided that this is an Unity quirk that I will not just hack but vaporize.

Got the Xinput DotNet. Order of initialization: first Input for net then SteamWorks. Coded my own input manager and it works well and handles disconnects normally. Well. The game now loses its DirectInput support but in fine with it... SteamInput just works albeit I've got some recommendations when my free prologue was tested on Steam Deck that the game defaults to the deck controls... And I coded the game to only keep track of the gamepad who did its first input but I can control this too. So just prefer going with the actual APIS and not relying on the legacy input system. I don't like the new unity input system too, and unity still allows you to implement your input the way you want to.

@TarVK
Copy link

TarVK commented Mar 29, 2023

Are there any updates on this? This issue is really blocking right now. I need to test controllers together with steam networking (it's the majority of my game). As far as I understand after reading this tread, the only work around requires you to build your application every time, there is no way to get controller + steam networking to work within the unity editor at once?

The exact issue has been identified as far as I understand, so is there any non-proper fix (that is not clean enough to implement officially in either steam/unity) I could perform locally? Building the application for every test I want to perform is not an acceptable solution as you could imagine.

@CreepyGnome
Copy link

Are there any updates on this? This issue is really blocking right now. I need to test controllers together with steam networking (it's the majority of my game). As far as I understand after reading this tread, the only work around requires you to build your application every time, there is no way to get controller + steam networking to work within the unity editor at once?

The exact issue has been identified as far as I understand, so is there any non-proper fix (that is not clean enough to implement officially in either steam/unity) I could perform locally? Building the application for every test I want to perform is not an acceptable solution as you could imagine.

@TarVK Yes, the issue has been identified long ago, and there is nothing Unity or this Steamworks.NET can do to fix it, as Steam is breaking the unwritten "rules" about hooking inputs and highjacking control and all around not being a good citizen in this situation. They would have to fix the Steam App to be more compatible with the OS and external Game Engines.

The primary "workaround" is to stop using Unity Input for controllers and just use it for Keyboard and Mouse. Then write your own Steam Controller input management around Steam Input using Steamworks.NET.

One alternative I head that works but I haven't tried myself is to use the Epic SDK instead of Steamworks and it has support for both Epic and Steam to allow you to write against it and release into both stores. Again I only heard this is an option that works but I have no tried it, not sure how they do this but they may be embedding SteamWorks own SDK in theirs as it is really the only way to deal with this. Meaning something or someone has to manage the crappy VDF files.

Another alternative is to not support steam or not to support controller input. Both of these options are not great and for many games are not viable.

@Paliverse
Copy link

For my application DSX on Steam which is made mainly for PS controllers, I can’t use my own communications method and use the steam api at the same time, since it hijacks, my own system used to communicate with the controllers completely stop working.

so I have to do dumb things that I didn’t need to do:

  1. Use a launcher that is explicitly used for the steam api and to launch the actual main app.
  2. For any steam api stuff, the launcher has to run again and then have to do communications between the main app and the launcher which does the steam api usage.

If steam just had an option for the devs, to completely disable the hijacking part aka steam input, then I would’ve been able to use the steam api while having my own controller communication system and not have to rely on a whole separate app just for api usage.

just doing Steam.Init() in my application which is just a WPF .NET app hijacks the normal Hid Library I have to directly read/send inputs to controllers.

All in all, I don’t think they will do anything about it, as it’s good for the games with lazy devs where steam takes care of things through hijacking. I understand their decision so that things just “work” outta the box, or without having to do a lot of work.

one last fix is to disable steam input in the game’s properties section, but that just means every user that downloads, has to also disable it manually vs just giving us devs some control on the input system.

@TarVK
Copy link

TarVK commented Mar 30, 2023

Thanks for the response @CreepyGnome. I however realized I didn't read carefully enough, and after some more fiddling, I found a development setup that seems acceptable for me.

I ended up launching the unity editor from steam, and using this 1456390 app id (I haven't tested if that part is crucial).
Launching the unity editor from steam required me to create a batch file that runs a specific unity editor version (instead of launching the hub) and supplies the project to open:

"my\path\to\unity.exe" -projectPath "my\path\to\project"

I then used iexpress to create an exe around this bat file, in order to add it to my steam game library.

I've not had the time to extensively test this setup yet, so there may be additional caveats. But I at least was able to get some response out of my controllers again this way.

@CreepyGnome
Copy link

Ahh sorry @TarVK I misunderstood what you were having issues with. If you want to be able to run the game in Unity and talk to Steam for a game you have set up and registered with Steamworks so you can debug and test from Unity and use the controller without deploying via steam, you can do something even simpler.

Try launching steam from a custom shortcut that looks like this (assuming that is your appid):

"C:\Program Files (x86)\Steam\steam.exe" -forcecontrollerappid 1456390

I run steam with that anytime I need to make sure the controller works with the game I am developing while steam is up and the other steam services will be happy as well. This requires you to have your VDF files set up and discoverably per Steam Input requirements, etc etc.

@sancarn
Copy link

sancarn commented Jan 18, 2024

Beware appid 1456390 does not exist anymore!! Do not use it!

https://store.steampowered.com/app/1456390 navigates to home page

image

Src: https://steamdb.info/app/1456390/charts/

@petersvp
Copy link

@slouken sorry for mentioning here, but I guess your answer will be better than Steam Support... I implemented SIAPI in 670510 / beta-4-unstable branch (as a VAlve Employee you know exactly what this mean) and I implemented Action Sets.
My game uses Unity, but I am NOT using any of its default input systems (except the old legacy one for keyboard).
For XInput I use https://github.com/speps/XInputDotNet, and SIAPI for everything else.

XInputDotNet only detects REAL hardware devices, and not emulated ones. SIAPI works perfectly when I use the configurations for Xbox, DualSense and Nintendo Switch controllers when the game is launched from steam or when I do forceunputappid/670510 cia cmd/run.

There is however an issue with the Steam Link Mobile app - There is not a wsay i can bind the virtual XBOX controller to work at all with the Unity Editor (and in a build, too). The application is not released yet... can you assist me? You can email me? my username is petersvp everywhere. including Discord and Steam

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests