Keyboard = p1 gamepad = p2 please!

Why has no one from Epic even looked into this yet after all these months?!? I mean this affects pretty much every local Co Op game made with UE4.
Having to spend so much time to come up with a blueprint setup for such a simple task makes me sad.

I’m waiting to see this feature as well in the next releases, hopefully Epic sees this thread.

I tried to come up with a solution for this. But I just can’t see a way to make the first player (controller) “give up” the inputs of the first gamepad and pass it on to the second player (controller) in blueprints.
Is there any progress on this huge problem yet?

Thanks, it works well, very usefull.

To do a dirty hacky keyboard/controller or keyboard/keyboard way you’ll have to setup duplicate inputs, one for player 1, the other for player 2.

e.g. Player1Up, Player2Up

These all get picked up from player 1’s player controller class, then you just send the input to the correct pawn.

Can I bump this thread? This really needs to be looked at again! Would be over the moon happy if they implemented a fix for this. Right now, I have a two player split screen game that I want to build + compile but I cant possibly send it out until there’s a fix for this.

I am bumping this because i think that after 14 new releases this should’ve been addressed already.

@sonicphi Actually, I think they have addressed this and forgot to tell anybody. At least, I read all of the 4.13 release notes and don’t recall seeing it mentioned.

Look at the bottom-right option in this screenshot from my current project in 4.13:

&stc=1

Haha that’s funny, but ye it does look like they forgot.

But still it feel a bit incomplete, the process to create coop be it on the key board only ( 2 players on the keyboard ) or game pad only ( game pads ) seems a bit clunky still.
What if i want my player 1 to be on the game pad and player 2 to be on the keyboard?

Imo they should add something like the input setup, where you can “add” players and specify if u want them on the keyboard, mouse or game pads.

With this it seems player 1 will always be forced to be on the keyboard no?

Hello there!

After searching a lot, I finally found a solution by talking to MordenTral (awesome dude and author of two amazing plugins). Basically, the clean solution to achieve this is to create a child class of UGameViewportClient which overrides InputKey(…) and InputAxis(…). In the overrides, you can reroute where certain inputs go and both functions have bool bGamepad as a parameter so you can basically use that to determine where you want to send the input. It is necessary to set the Game Viewport Client Class in Project Settings to be the newly created class. You can make this class blueprintable and expose an Enum UPROPERTY to Blueprint so that you can actually create a child blueprint class and can change behavior dynamically at runtime using blueprints (of course the Game Viewport Client Class in Project Settings would need to point to this blueprint class).

Here is the answer on AnswrHub: https://answers.unrealengine.com/questions/330383/simply-allow-first-gamepad-to-control-player-2.html?childToView=779572#answer-779572

Here is my UCustomGameViewportClient class:

#pragma once

#include "CoreMinimal.h"
#include "Engine/GameViewportClient.h"
#include "CustomGameViewportClient.generated.h"

/** This class introduces a new Input-PlayerController binding behaviour. Through the EGameInputMethod Enum it is possible to choose the default
* behavior (in which keyboard/mouse input and gamepad input are both binded to Player 1 [index 0]) or the Player1OnlyKeyboardAndMouse behavior 
* (in which keyboard/mouse input is binded to Player 1 [index 0] and gamepad input is shifted to the other players).
*/
UENUM(Blueprintable)
enum class EGameInputMethod : uint8
{
    GameInput_Default,
    GameInput_Player1OnlyKeyboardAndMouse,
};

UCLASS(Blueprintable)
class SIDESCROLLER_API UCustomGameViewportClient : public UGameViewportClient
{
    GENERATED_BODY()

public:

    // Input Method for the viewport
    UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Input")
        EGameInputMethod GameInputMethod;


    virtual bool InputKey(FViewport* tViewport, int32 ControllerId, FKey Key, EInputEvent EventType, float AmountDepressed = 1.f, bool bGamepad = false) override
    {
        if (GameInputMethod == EGameInputMethod::GameInput_Default)
            return Super::InputKey(tViewport, ControllerId, Key, EventType, AmountDepressed, bGamepad);

        if (GameInputMethod == EGameInputMethod::GameInput_Player1OnlyKeyboardAndMouse && bGamepad)
        {
            // shift gamepad input to controllers with +1 index
            ++ControllerId;
            return Super::InputKey(tViewport, ControllerId, Key, EventType, AmountDepressed, bGamepad);
        }
        else 
        {
            return Super::InputKey(tViewport, ControllerId, Key, EventType, AmountDepressed, bGamepad);
        }
    }

    virtual bool InputAxis(FViewport* tViewport, int32 ControllerId, FKey Key, float Delta, float DeltaTime, int32 NumSamples = 1, bool bGamepad = false) override
    {
        if (GameInputMethod == EGameInputMethod::GameInput_Default)
            return Super::InputAxis(tViewport, ControllerId, Key, Delta, DeltaTime, NumSamples, bGamepad);

        if (GameInputMethod == EGameInputMethod::GameInput_Player1OnlyKeyboardAndMouse && bGamepad)
        {
            // shift gamepad input to controllers with +1 index
            ++ControllerId;
            return Super::InputAxis(tViewport, ControllerId, Key, Delta, DeltaTime, NumSamples, bGamepad);
        }
        else
        {
            return Super::InputAxis(tViewport, ControllerId, Key, Delta, DeltaTime, NumSamples, bGamepad);
        }
    }


};

Create Blueprint class from this, and you’ll see ou can change the Enum to whatever you like.

To change this at runtime you’ll need to access this class with UWorld::GetGameViewport(), so make a function in a c++ blueprint function library (if you want to have access via Blueprints):

class UGameViewportClient* FunctionLibrary::GetGameViewport(const UObject* WorldContextObject)
{
    UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
    return World ? World->GetGameViewport() : nullptr;
}

Once you have that exposed, all you need to do is cast it to your custom Game Viewport class and set the enum to the desired value.

I must say that this works perfectly for me… but I also have input on UI and in that case, it isn’t working, I still need to find out what happens in that case.

That’s how I would have done it. It would be great if Epic would go back on their 4.13 feature and give it a bit of a rework, so we don’t have to use a c++ hack.

The way JohnnyDale explained it above is the correct way of doing it, it is extremely simple to implement and works without any hacks.

If you want a “simpliest” solution without changing the **GameViewportClient **class, you can handle it by “simply” changing the Game Map Settgins in your game instance.
This other class is already call by the GameViewport to check if it should offset (++controllerId) gamepads to “skip associating the first gamepad to the keyboard” (by the variable bOffsetPlayerGamepadIds).

In my case, I expose a function to Blueprints like so :

MyGameInstance.h



    /**
    * Allow to set if keyboard and gamepad should be associate to same player
    */
    UFUNCTION(BlueprintCallable, Category = "Controllers")
    void AssociateGamepadToKeyboard(bool ShouldBeAssociated);


MyGameInstance.cpp



void MyGameInstance::AssociateGamepadToKeyboard(bool ShouldBeAssociated) {
    // Get GameSettings
    auto Settings = const_cast<UGameMapsSettings*>(GetDefault<UGameMapsSettings>());

    // It will affect Gamepad from Controller 1 (and keyboard to 1) if they should not be associated
    Settings->bOffsetPlayerGamepadIds = !ShouldBeAssociated;
}


Do not forget to include (MyGameInstance.h) “GameMapsSettings.h” and add the public dependency (Project.Build.cs) to “EngineSettings”.

1 Like

I actually have a PR to set up mapping between player controllers and devices (so you can control more player controllers with one keyboard, control player 1 with gamepad 2 and player 2 with keyboard, or whichever combination you like): https://github.com/EpicGames/UnrealEngine/pull/5209

If you have a source build project, feel free to try it out and give feedback if you find anything to be broken (or if it works for you)!

Is this still not possible to do in 2023? I am trying to have my gamepad working in one window and keyboard/mouse in another, but I cant seem to fix that with blueprint only. Am I right this is still an issue?

Its hardly believable with so much focus on cross-play that this hasnt been handled so I am curious to hear your answers!

hey, i have same issue with ue5.1 :frowning:

Yep, issue still persists in 5.3.2. This has gone on for much too long and this functionality needs to be added.

  • Why hasn’t this feature been built yet? What is the development team doing?