bAllowControllers

bAllowControllers

#Overview

name: bAllowControllers

The value of this variable can be defined or overridden in .ini config files. 2 .ini config files referencing this setting variable.

It is referenced in 20 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of bAllowControllers is to enable or disable input from Bluetooth-connected controllers on mobile platforms, specifically iOS and Android.

This setting variable is primarily used by the input subsystem in Unreal Engine, particularly in the CommonInput plugin and the ApplicationCore module. It’s also referenced in platform-specific settings classes for iOS and Android.

The value of this variable is typically set in the platform-specific runtime settings. For iOS, it’s set in IOSRuntimeSettings, and for Android, it’s set in AndroidRuntimeSettings. These settings can be configured in the project settings within the Unreal Engine editor.

bAllowControllers interacts with other variables related to controller input, such as bBlockAndroidKeysOnControllers and bControllersBlockDeviceFeedback. These variables work together to define the behavior of controller input on mobile platforms.

Developers must be aware that this variable affects the entire input system for controllers on mobile platforms. When set to false, it will disable all controller input, which could significantly impact gameplay if controllers are a primary input method for the game.

Best practices when using this variable include:

  1. Ensuring it’s properly set in the project settings for the target platform.
  2. Considering the impact on gameplay and user experience when enabling or disabling controller input.
  3. Testing the game thoroughly with both controllers enabled and disabled to ensure proper functionality in all scenarios.
  4. If controller input is critical for the game, consider adding a runtime check to inform users if controller input is disabled but required for gameplay.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEngine.ini:2991, section: [/Script/IOSRuntimeSettings.IOSRuntimeSettings]

Location: <Workspace>/Engine/Config/BaseEngine.ini:3076, section: [/Script/AndroidRuntimeSettings.AndroidRuntimeSettings]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/Runtime/CommonUI/Source/CommonInput/Private/CommonInputSubsystem.cpp:534

Scope (from outer to inner):

file
function     bool UCommonInputSubsystem::PlatformSupportsInputType

Source code excerpt:

#if PLATFORM_IOS
		{
			bool bAllowControllers = false;
			GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bAllowControllers"), bAllowControllers, GEngineIni);
			bPlatformSupportsInput &= bAllowControllers;
		}
#elif PLATFORM_ANDROID
		{
			bool bAllowControllers = false;
			GConfig->GetBool(TEXT("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings"), TEXT("bAllowControllers"), bAllowControllers, GEngineIni);
			bPlatformSupportsInput &= bAllowControllers;
		}
#endif
		break;
	}

	GetOnPlatformInputSupportOverride().Broadcast(GetLocalPlayer(), InInputType, bPlatformSupportsInput);

#Loc: <Workspace>/Engine/Source/Runtime/Android/AndroidRuntimeSettings/Classes/AndroidRuntimeSettings.h:548

Scope (from outer to inner):

file
class        class UAndroidRuntimeSettings : public UObject

Source code excerpt:

	// If checked, Bluetooth connected controllers will send input
	UPROPERTY(GlobalConfig, EditAnywhere, Category = Input, meta = (DisplayName = "Allow Bluetooth controllers"))
	bool bAllowControllers;

	// If checked, controllers will not send Android_Back and Android_Menu events that might cause unnecce
	UPROPERTY(GlobalConfig, EditAnywhere, Category = Input, meta = (DisplayName = "Block Android system keys being sent from controllers"))
	bool bBlockAndroidKeysOnControllers;

	// Block force feedback on the device when controllers are attached.

#Loc: <Workspace>/Engine/Source/Runtime/Android/AndroidRuntimeSettings/Private/AndroidRuntimeSettings.cpp:56

Scope (from outer to inner):

file
function     void UAndroidRuntimeSettings::PostReloadConfig

Source code excerpt:

#if PLATFORM_ANDROID

	FPlatformApplicationMisc::SetGamepadsAllowed(bAllowControllers);

#endif //PLATFORM_ANDROID
}

#if WITH_EDITOR

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidInputInterface.cpp:28

Scope: file

Source code excerpt:

FForceFeedbackValues FAndroidInputInterface::VibeValues;

bool FAndroidInputInterface::bAllowControllers = true;
bool FAndroidInputInterface::bBlockAndroidKeysOnControllers = false;
bool FAndroidInputInterface::bControllersBlockDeviceFeedback = false;

FAndroidControllerData FAndroidInputInterface::OldControllerData[MAX_NUM_CONTROLLERS];
FAndroidControllerData FAndroidInputInterface::NewControllerData[MAX_NUM_CONTROLLERS];
FAndroidControllerVibeState FAndroidInputInterface::ControllerVibeState[MAX_NUM_CONTROLLERS];

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidInputInterface.cpp:97

Scope (from outer to inner):

file
function     FAndroidInputInterface::FAndroidInputInterface

Source code excerpt:

	, Cursor(InCursor)
{
	GConfig->GetBool(TEXT("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings"), TEXT("bAllowControllers"), bAllowControllers, GEngineIni);
	GConfig->GetBool(TEXT("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings"), TEXT("bBlockAndroidKeysOnControllers"), bBlockAndroidKeysOnControllers, GEngineIni);
	GConfig->GetBool(TEXT("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings"), TEXT("bControllersBlockDeviceFeedback"), bControllersBlockDeviceFeedback, GEngineIni);

	ButtonMapping[0] = FGamepadKeyNames::FaceButtonBottom;
	ButtonMapping[1] = FGamepadKeyNames::FaceButtonRight;
	ButtonMapping[2] = FGamepadKeyNames::FaceButtonLeft;

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidInputInterface.cpp:982

Scope (from outer to inner):

file
function     void FAndroidInputInterface::SendControllerEvents

Source code excerpt:


	// Check for gamepads needing validation if enabled
	if (bAllowControllers)
	{
		for (int32 DeviceIndex = 0; DeviceIndex < MAX_NUM_CONTROLLERS; DeviceIndex++)
		{
			FAndroidGamepadDeviceMapping& CurrentDevice = DeviceMapping[DeviceIndex];

			if (CurrentDevice.DeviceState == MappingState::ToValidate)

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidInputInterface.cpp:1233

Scope (from outer to inner):

file
function     void FAndroidInputInterface::SendControllerEvents

Source code excerpt:


	// Extract differences in new and old states and send messages
	if (bAllowControllers)
	{
		for (int32 ControllerIndex = 0; ControllerIndex < MAX_NUM_CONTROLLERS; ControllerIndex++)
		{
			// Skip unassigned or invalid controllers (treat first one as special case)
			if (ControllerIndex > 0 && (DeviceMapping[ControllerIndex].DeviceState !=  MappingState::Valid))
			{

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidInputInterface.cpp:1445

Scope (from outer to inner):

file
function     int32 FAndroidInputInterface::FindExistingDevice

Source code excerpt:

int32 FAndroidInputInterface::FindExistingDevice(int32 deviceId)
{
	if (!bAllowControllers)
	{
		return -1;
	}
	
	// Treat non-positive devices ids special
	if (deviceId < 1)

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidInputInterface.cpp:1477

Scope (from outer to inner):

file
function     int32 FAndroidInputInterface::GetControllerIndex

Source code excerpt:

int32 FAndroidInputInterface::GetControllerIndex(int32 deviceId)
{
	if (!bAllowControllers)
	{
		return -1;
	}
	
	// Treat non-positive device ids special (always controller 0)
	if (deviceId < 1)

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Apple/AppleControllerInterface.cpp:16

Scope (from outer to inner):

file
function     FAppleControllerInterface::FAppleControllerInterface

Source code excerpt:

FAppleControllerInterface::FAppleControllerInterface( const TSharedRef< FGenericApplicationMessageHandler >& InMessageHandler )
	: MessageHandler( InMessageHandler )
	, bAllowControllers(true)
{
	if(!IS_PROGRAM)
	{
		// Clear array and setup unset player index values
		FMemory::Memzero(Controllers, sizeof(Controllers));
		for (int32 ControllerIndex = 0; ControllerIndex < UE_ARRAY_COUNT(Controllers); ControllerIndex++)

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Apple/AppleControllerInterface.cpp:167

Scope: file

Source code excerpt:

	static_assert(GCControllerPlayerIndex1 == 0 && GCControllerPlayerIndex4 == 3, "Apple changed the player index enums");

	if (!bAllowControllers)
	{
		return;
	}
	
	static_assert(GCControllerPlayerIndex1 == 0 && GCControllerPlayerIndex4 == 3, "Apple changed the player index enums");

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Apple/AppleControllerInterface.cpp:217

Scope: file

Source code excerpt:

{
		// if we don't allow controllers, there could be unset player index here
	if (!bAllowControllers)
	{
        return;
	}
	
    for (int32 ControllerIndex = 0; ControllerIndex < UE_ARRAY_COUNT(Controllers); ControllerIndex++)
    {

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Apple/AppleControllerInterface.cpp:334

Scope: file

Source code excerpt:

		bIsAttached |= IsControllerAssignedToGamepad(i);
	}
	return bIsAttached && bAllowControllers;
}

GCControllerButtonInput* FAppleControllerInterface::GetGCControllerButton(const FGamepadKeyNames::Type& ButtonKey, uint32 ControllerIndex)
{
    GCController* Cont = Controllers[ControllerIndex].Controller;
    

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/Apple/AppleControllerInterface.h:152

Scope (from outer to inner):

file
class        class FAppleControllerInterface : public IInputInterface

Source code excerpt:

	
	// should we allow controllers to send input
	bool bAllowControllers;
};

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSInputInterface.cpp:118

Scope (from outer to inner):

file
function     FIOSInputInterface::FIOSInputInterface

Source code excerpt:

    GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bGameSupportsMultipleActiveControllers"), bGameSupportsMultipleActiveControllers, GEngineIni);
    GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bAllowRemoteRotation"), bAllowRemoteRotation, GEngineIni);
    GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bAllowControllers"), bAllowControllers, GEngineIni);
    GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bControllersBlockDeviceFeedback"), bControllersBlockDeviceFeedback, GEngineIni);
    
    
    NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
    NSOperationQueue* currentQueue = [NSOperationQueue currentQueue];
    

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Public/Android/AndroidInputInterface.h:273

Scope (from outer to inner):

file
class        class FAndroidInputInterface : public IInputInterface
function     void SetGamepadsAllowed

Source code excerpt:

	virtual void ResetLightColor(int32 ControllerId) override;

	void SetGamepadsAllowed(bool bAllowed) { bAllowControllers = bAllowed; }
	void SetGamepadsBlockDeviceFeedback(bool bBlock) { bControllersBlockDeviceFeedback = bBlock; }

	virtual bool IsGamepadAttached() const;


	virtual void AddExternalInputDevice(TSharedPtr<class IInputDevice> InputDevice);

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Public/Android/AndroidInputInterface.h:345

Scope (from outer to inner):

file
class        class FAndroidInputInterface : public IInputInterface

Source code excerpt:


	// should we allow controllers to send input
	static bool bAllowControllers;

	// bluetooth connected controllers will block force feedback.
	static bool bControllersBlockDeviceFeedback;

	// should we allow controllers to send Android_Back and Android_Menu events
	static bool bBlockAndroidKeysOnControllers;

#Loc: <Workspace>/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSInputInterface.h:88

Scope (from outer to inner):

file
class        class FIOSInputInterface : public FAppleControllerInterface, FSelfRegisteringExec
function     void SetGamepadsAllowed

Source code excerpt:

	static void QueueKeyInput(int32 Key, int32 Char);

	void SetGamepadsAllowed(bool bAllowed) { bAllowControllers = bAllowed; }
	void SetGamepadsBlockDeviceFeedback(bool bBlock) { bControllersBlockDeviceFeedback = bBlock; }

	void EnableMotionData(bool bEnable);
	bool IsMotionDataEnabled() const;
    
    static void SetKeyboardInhibited(bool bInhibited) { bKeyboardInhibited = bInhibited; }

#Loc: <Workspace>/Engine/Source/Runtime/IOS/IOSRuntimeSettings/Classes/IOSRuntimeSettings.h:352

Scope (from outer to inner):

file
class        class UIOSRuntimeSettings : public UObject

Source code excerpt:

	// If checked, Bluetooth connected controllers will send input
	UPROPERTY(GlobalConfig, EditAnywhere, Category = Input, meta = (DisplayName = "Allow MFi (Bluetooth) controllers"))
	bool bAllowControllers;

	// Block force feedback on the device when controllers are attached.
	UPROPERTY(GlobalConfig, EditAnywhere, Category = Input, meta = (DisplayName = "Block force feedback on the device when controllers are attached"))
	bool bControllersBlockDeviceFeedback;

	// Disables usage of device motion data. If application does not use motion data disabling it will improve battery life

#Loc: <Workspace>/Engine/Source/Runtime/IOS/IOSRuntimeSettings/Private/IOSRuntimeSettings.cpp:70

Scope (from outer to inner):

file
function     void UIOSRuntimeSettings::PostReloadConfig

Source code excerpt:

#if PLATFORM_IOS

	FPlatformApplicationMisc::SetGamepadsAllowed(bAllowControllers);

#endif //PLATFORM_IOS
}

#if WITH_EDITOR
void UIOSRuntimeSettings::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)