I have more than this, but this is the most important stuff:
var OnlineSubsystemSteamworks Steamworks;
...
local bool Success;
Steamworks = OnlineSubsystemSteamworks(class'GameEngine'.static.GetOnlineSubsystem());
Success = Steamworks.ShowKeyboardUI(0, EnterCharacterName_Localized, "", false, true, "", 64);
It always fails. (I also tried a loop to try all the possible LocalUserNum values from 0 through 255.)
Does OnlineSubsystemSteamworks.ShowKeyboardUI() do anything? I looked at it, and it’s not a native function and it’s empty.
Am I going to have to go into native code and get my own access to SteamUtils()->ShowGamepadTextInput()
or SteamUtils()->ShowFloatingGamepadTextInput()
?
Edit: In Steam, I have “Enable the Steam Overlay while in-game” and “Use the Big Picture Overlay when using a Steam Input enabled controller from the desktop” checked.
OK, a little progress here. I wrote my own UnrealScript wrapper for SteamUtils. I can get a text input window to appear when Steam Big Picture is active. I can only get Big Picture to work if I launch my game through the Steam client. I cannot find any way to launch the game with Big Picture activated, when launching from Visual Studio or a shortcut. Launching from the Steam client isn’t so bad, if I add my local development build exe as a non-Steam game, so I don’t have to upload every iteration through steamcmd just so I can test. But now it seems I can’t use my controller for some reason when launching through the Steam client as a non-Steam game. Ugh. There’s always something.
Now I need to figure out how to set up a callback to get the text when the text input window closes.
(Edit: Just to confirm there is a problem with the stock OnlineSubsystemSteamworks implementation, I tried using Steamworks.ShowKeyboardUI
as shown in my first post, when launching from the Steam client. The keyboard overlay still does not appear even when Big Picture mode is active, when I launch from the Steam client.)
I ended up writing a dll to wrap the latest Steam SDK and linking with a DllBind (with the help of a knowledgeable modder), as the one included in UDK is old and doesn’t include many of the current features. This has allowed me to use the Steam Inventory Service and implement a system for weapon/clothing/item skins from the Steam store. Using DllBinds with the 64 bit executable is a bit tricky though, as you need to wrap the payload sent from US to the DLL to mimic that of the 64 bit structure.
@Nathaniel3W How did you manage to get access to SteamUtils(), or was that included in the old SDK and just not exposed through US?
I downloaded the latest Steamworks SDK and I had to make a new native class:
class SteamUtilsWrapper extends Object native;
var protected array<Object> ObjectsWaitingForCallback;
var string GamepadTextInput;
var bool TextInputWasCanceled;
// native function bool BOverlayNeedsPresent(); // No need to ever call this manually
native function int GetAppID();
native function byte GetCurrentBatteryPower();
native function int GetSecondsSinceAppActive();
native function int GetSecondsSinceComputerActive();
native function bool IsOverlayEnabled();
native function bool IsSteamChinaLauncher();
native function bool IsSteamInBigPictureMode();
native function bool IsSteamRunningOnSteamDeck();
native function SetOverlayNotificationInset(int nHorizontalInset, int nVerticalInset);
native function SetOverlayNotificationPosition(byte byteNotificationPosition);
native function bool ShowGamepadTextInput(byte eInputMode, byte eLineInputMode, string Description, int MaxChar, string ExistingText);
// native function bool ShowFloatingGamepadTextInput(byte eKeyboardMode, int nTextFieldXPosition, int nTextFieldYPosition, int nTextFieldWidth, int nTextFieldHeight); // only useful on Steam Deck
// native function WrapperRunCallbacks(); // The game engine runs this automatically. No need to call it manually.
function bool WaitingForCallback()
{
return ObjectsWaitingForCallback.Length > 0 ? true : false;
}
function AddToWaitForCallback(Object ObjectWaitingForCallback)
{
if(TextInputDismissedInterface(ObjectWaitingForCallback) != none)
{
ObjectsWaitingForCallback.AddItem(ObjectWaitingForCallback);
}
}
event NotifyTextInputCallbacks()
{
local Object ObjectWaitingForCallback;
foreach ObjectsWaitingForCallback(ObjectWaitingForCallback)
{
if(TextInputDismissedInterface(ObjectWaitingForCallback) != none)
{
TextInputDismissedInterface(ObjectWaitingForCallback).OnTextInputDismissed(self);
}
}
ObjectsWaitingForCallback.Length = 0;
}
cpptext
{
#include "isteamutils.h" // ************************************************ Remember to cut/paste this to the top of RPGTacGameClasses.h
#include "steam_api_common.h" // ************************************************ Remember to cut/paste this to the top of RPGTacGameClasses.h
#include "steamclientpublic.h" // ************************************************ Remember to cut/paste this to the top of RPGTacGameClasses.h
private:
STEAM_CALLBACK( USteamUtilsWrapper, OnGamepadTextInputDismissed_t, GamepadTextInputDismissed_t );
}
Make that UScript class, build UScript which will make new header files, then move the #include
statements to the top of the header (there’s a way to set up the Unreal Build Tool so that it automatically creates your headers with the #include
s in the right place, but I never figured that out), then fill in your functions in the cpp file, and build the C++.
It took me a while to do all of that, mostly because I never learned C++. Now that I’ve done it all and I have working code, I think the code looks pretty simple. I don’t have any of the functionality you mentioned–I only really needed the text input window–but I think I could add more SteamUtils functions if I needed them.
Everything is working perfectly, except instantiating my SteamUtils object crashes the game when you’re running the 32 bit exe. I never figured out a way to know directly from UScript whether the game is 32 or 64 bit. So I added an option to my startup command (?win32=true) to tell the game whether I intended to run the 32 bit exe, and I look for that option before creating SteamUtils.
My 32-bit players just have to do without SteamUtils for now.
Thanks for the info @Nathaniel3. Very useful!