Francesco Camarlinghi

Game Developer

Switcheroo is a lightweight plugin for UE4 that makes it easy to detect whether the player is using a gamepad or the keyboard/mouse combo, and react accordingly.

Features

  • State-of-the-art input detection. The plugin automatically filters out edge cases and false positives (such as input coming from a loose analog stick, or from involuntary mouse movements) and is highly customizable.
  • Plug and Play. The plugin doesn't require any special setup (like custom GameInstance or PlayerController classes): enabling the plugin is all it takes to be up-and-running.
  • Easy to use. Switcheroo provides a simple API that can be used from both Blueprints and C++.
  • Lightweight. The plugin logic is implemented in native C++ code and runs at the Slate application level with no impact on performance.
  • Supported. The plugin is actively used in my company's upcoming game, and will receive all the needed lifetime upgrades.
  • Full source code. Switcheroo comes with full, heavily commented source code.

Usage

Quick Start

1) Enable the Plugin

First of all make sure the plugin is enabled in the Edit ➜ Plugins panel:

A screenshot of the plugin panel in UE4, with Switcheroo enabled

If you plan to use the plugin from C++, don't forget to list it in your build dependencies:

using UnrealBuildTool;

public class MyGame : ModuleRules
{
    public MyGame(ReadOnlyTargetRules Target)
        : base(Target)
    {
        // [...]

        // No input to detect on dedicated servers :)
        if (Target.Type != TargetRules.TargetType.Server)
        {
            PrivateDependencyModuleNames.Add("Switcheroo");
        }

        // [...]
    }
}
2) Enable Input Detection

Then turn on input detection using the Enable Input Detection node or the equivalent C++ function. You can do this anywhere you like: inside a Level Blueprint, inside an Actor, in a UMG widget, etc.

Usage of the "Enable Input Detection" node inside the Blueprint editor
#include "ISwitcherooModule.h"

void AMyActor::BeginPlay()
{
    Super::BeginPlay();

    if (ISwitcherooModule* Switcheroo = ISwitcherooModule::Get())
    {
        Switcheroo->EnableInputDetection();
    }
}
3) React to Input Device Changes

Switcheroo will fire-off an event every time the input device used by the player changes. You can react to this event by using the Bind Detected Input Device Changed node or the equivalent C++ function.

Example setup to react to an input changed event
#include "ISwitcherooModule.h"
#include "SwitcherooTypes.h"

void UMyWidget::NativeConstruct()
{
    Super::NativeConstruct();

    if (ISwitcherooModule* Switcheroo = ISwitcherooModule::Get())
    {
        Switcheroo->OnDetectedInputDeviceChanged().AddUObject(this, &UMyWidget::OnDetectedInputDeviceChanged);
    }
}

void UMyWidget::OnDetectedInputDeviceChanged(ESwitcherooInputDevice ActiveInputDevice)
{
    // React to the event
}

Example Project

An example project that shows how to use the plugin is available for download for Unreal Engine 4.18 and up.

The project implements a complete menu system demonstrating how Switcheroo can be used to show the appropriate UI controls to the player and show/hide the mouse cursor. It also implements a simple game mode to demonstrate usage during gameplay.

Settings

Switcheroo provides a simple set of options to customize its behavior. These can be changed in the editor by navigating to the Plugins / Switcheroo section of the Edit ➜ Project Settings menu. It's also possible to modify them at runtime using either C++ or Blueprints (for more information head over to the API Reference section).

A screenshot of the Switcheroo settings screen

A description of each setting is available below, as well as by hovering over a setting inside the editor.

NameDescription
General
Default Input DeviceDefault input device to use when no input has been detected yet. Can be used to select an appropriate default on different platforms (e.g. keyboard on PCs, gamepad on consoles).
Keyboard/Mouse
Mouse Move Threshold

The minimum movement that the mouse should perform in order for it to be considered valid input. Useful to filter out involuntary, minimal mouse movements.

Resolution independent, defined in Slate units. Set to zero to disable.

Gamepad
Analog StickDetermines which analog stick should be watched for input.
Dead Zone ModeDetermines which type of dead zone should be applied to the input provided by gamepad analog sticks. Useful to filter out involuntary, minimal stick movements which can happen i.e. with loose analog sticks.
Dead Zone SizeSize of the dead zone applied to the input provided by gamepad analog sticks.

Limitations

There are some issues of which I'm aware of that are unfortunately out of my control.

1) Only input from the first player will be detected.

As such, scenarios that involve multiple local players aren't supported out-of-the-box. This is due to the fact that only the primary player can be bound to the keyboard/mouse combo in Unreal Engine 4. Although there are some ways to work around that, they usually involve some gimmicks that would make the plugin unnecessarily complicated for most users and hard to maintain.

2) Switcheroo won't respect the Skip Assigning Gamepad to Player 1 option.

This is by design and is due to the way that option is implemented (at the viewport level, rather than at the Slate level). Fortunately there's a simple workaround: in case you're using that option, simply turn off input detection. Since Unreal Engine 4 only routes keyboard input to the first player, and you know gamepad input will always be routed to the second player, you won't need it anyway. 😉

3) Input detection doesn't work correctly in multi-window PIE.

Due to the way Slate users are mapped to each single window in multi-window Play in Editor (PIE), input detection will run on all the windows at the same time. This results in input detection events to be fired in all the PIE instances at the same time.


API Reference

To make it easier to work with Switcheroo, the C++ API and the Blueprint API are largely the same. The plugin API is designed to be simple to use and self-explanatory.

Blueprint API

All the available Blueprint nodes are listed below, alongside Switcheroo types and a couple of utility functions. These are used internally by the plugin, but can also be useful in some cases (e.g. if you want to apply the same dead zone used by the plugin to your game input). Documentation for each node is available by hovering it inside the editor.

All the available Blueprint nodesAll the available Blueprint nodes to interact with settings

C++ API

All the methods live inside the ISwitcherooModule class, and can be called on the Switcheroo module instance (see the usage section for additional information). Documentation is available directly in the code for all methods and types.

class SWITCHEROO_API ISwitcherooModule : public IModuleInterface
{

    // [...]

public:

    /** Gets whether the detection of the input device is enabled or disabled. */
    virtual bool IsInputDetectionEnabled() const = 0;

    /** Enables detection of the input device. */
    virtual void EnableInputDetection() = 0;

    /** Disables detection of the input device. */
    virtual void DisableInputDetection() = 0;

    /** Enables or disables detection of the input device. */
    virtual void SetInputDetectionEnabled(const bool bEnabled) = 0;

    /**
     * Gets the detected input device.
     * @returns The active input device if one has been detected; otherwise, the default input device specified in project settings.
     */
    virtual ESwitcherooInputDevice GetDetectedInputDevice() const = 0;

    /** Event fired when the detected input device changes. */
    DECLARE_EVENT_OneParam(ISwitcherooModule, FSwitcherooInputDeviceChangedEvent, ESwitcherooInputDevice /* ActiveInputDevice */);
    virtual FSwitcherooInputDeviceChangedEvent& OnDetectedInputDeviceChanged() = 0;

    // [...]

};

Settings can be accessed using the USwitcherooSettings default object:

// Get the "Default Input Device" option
const ESwitcherooInputDevice DefaultDevice = GetDefault<USwitcherooSettings>()->GetDefaultInputDevice();

// Set the "Default Input Device" option
GetMutableDefault<USwitcherooSettings>()->SetDefaultInputDevice(ESwitcherooInputDevice::KeyboardMouse);

Support

If you experience issues with the plugin that are not covered in the documentation, feel free to get in touch! The preferred support channel is the dedicated thread (coming soon!) in the Unreal Engine 4 forums. This way solutions shared there might help users facing the same issue in the future.

Alternatively, you can hit me on Twitter or contact me by e-mail. Please allow at least a business day for me to get back to you!

« Back to tools | ⇑ Back to top