2
2
3
3
#include " MyUtilsLibraries/InputUtilsLibrary.h"
4
4
// ---
5
- #include " MyUtilsLibraries/UtilsLibrary.h"
6
- // ---
7
5
#include " EnhancedActionKeyMapping.h"
8
6
#include " EnhancedInputComponent.h"
9
7
#include " EnhancedInputSubsystems.h"
12
10
#include " Engine/Engine.h"
13
11
#include " Engine/LocalPlayer.h"
14
12
#include " GameFramework/PlayerController.h"
15
- #include " MyUtilsLibraries/GameplayUtilsLibrary .h"
13
+ #include " UserSettings/EnhancedInputUserSettings .h"
16
14
// ---
17
15
#include UE_INLINE_GENERATED_CPP_BY_NAME(InputUtilsLibrary)
18
16
@@ -42,6 +40,13 @@ UEnhancedPlayerInput* UInputUtilsLibrary::GetEnhancedPlayerInput(const UObject*
42
40
return PlayerController ? Cast<UEnhancedPlayerInput>(PlayerController->PlayerInput ) : nullptr ;
43
41
}
44
42
43
+ // Returns the Enhanced Input User Settings for remapping keys
44
+ class UEnhancedInputUserSettings * UInputUtilsLibrary::GetEnhancedInputUserSettings (const UObject* WorldContext)
45
+ {
46
+ const UEnhancedInputLocalPlayerSubsystem* InputSubsystem = GetEnhancedInputSubsystem (WorldContext);
47
+ return InputSubsystem ? InputSubsystem->GetUserSettings () : nullptr ;
48
+ }
49
+
45
50
/* ********************************************************************************************
46
51
* Input Contexts
47
52
********************************************************************************************* */
@@ -159,44 +164,15 @@ bool UInputUtilsLibrary::IsInputActionBound(const UObject* WorldContext, const U
159
164
* Mappings
160
165
********************************************************************************************* */
161
166
162
- // Returns keys mapped to this action in the active input mapping contexts sorted by its priorities
163
- void UInputUtilsLibrary::GetAllMappingsInAction (const UObject* WorldContext, const UInputAction* InInputAction, TArray<FKey>& OutKeys)
164
- {
165
- if (!ensureMsgf (InInputAction, TEXT (" ASSERT: [%i] %s:\n 'InInputAction' is not valid!" ), __LINE__, *FString (__FUNCTION__)))
166
- {
167
- return ;
168
- }
169
-
170
- const UEnhancedInputLocalPlayerSubsystem* EnhancedInputSubsystem = GetEnhancedInputSubsystem (WorldContext);
171
- if (!EnhancedInputSubsystem)
172
- {
173
- return ;
174
- }
175
-
176
- if (!OutKeys.IsEmpty ())
177
- {
178
- OutKeys.Empty ();
179
- }
180
-
181
- OutKeys = EnhancedInputSubsystem->QueryKeysMappedToAction (InInputAction);
182
- }
183
-
184
- // Returns the first mapped key to this action in most priority active input context
185
- FKey UInputUtilsLibrary::GetFirstMappingInAction (const UObject* WorldContext, const UInputAction* InInputAction)
186
- {
187
- TArray<FKey> OutKeys;
188
- GetAllMappingsInAction (WorldContext, InInputAction, OutKeys);
189
-
190
- constexpr int32 KeyIndex = 0 ;
191
- static const FKey EmptyKey{};
192
- return OutKeys.IsValidIndex (KeyIndex) ? OutKeys[KeyIndex] : EmptyKey;
193
- }
194
-
195
167
// Returns all mappings where bIsPlayerMappable is true
196
- void UInputUtilsLibrary::GetAllMappingsInContext (const UInputMappingContext* InInputContext, TArray<FEnhancedActionKeyMapping >& OutMappings)
168
+ void UInputUtilsLibrary::GetAllMappingsInContext (const UObject* WorldContext, const UInputMappingContext* InInputContext, TArray<FPlayerKeyMapping >& OutMappings)
197
169
{
198
- if (!ensureMsgf (InInputContext, TEXT (" ASSERT: [%i] %s:\n 'InInputContext' is not valid!" ), __LINE__, *FString (__FUNCTION__)))
170
+ const UEnhancedInputLocalPlayerSubsystem* InputSubsystem = GetEnhancedInputSubsystem (WorldContext);
171
+ const UEnhancedInputUserSettings* EnhancedInputUserSettings = InputSubsystem ? InputSubsystem->GetUserSettings () : nullptr ;
172
+ if (!ensureMsgf (EnhancedInputUserSettings, TEXT (" ASSERT: [%i] %hs:\n 'EnhancedInputUserSettings' is null, make sure 'Enable User Settings' is enabled in the Project Settings!" ), __LINE__, __FUNCTION__)
173
+ || !ensureMsgf (InInputContext, TEXT (" ASSERT: [%i] %hs:\n 'InInputContext' is not valid!" ), __LINE__, __FUNCTION__))
199
174
{
175
+ // Can be null on remote clients, do nothing
200
176
return ;
201
177
}
202
178
@@ -208,61 +184,56 @@ void UInputUtilsLibrary::GetAllMappingsInContext(const UInputMappingContext* InI
208
184
const TArray<FEnhancedActionKeyMapping>& AllMappings = InInputContext->GetMappings ();
209
185
for (const FEnhancedActionKeyMapping& MappingIt : AllMappings)
210
186
{
211
- if (MappingIt.IsPlayerMappable ())
187
+ if (! MappingIt.IsPlayerMappable ())
212
188
{
213
- OutMappings. Emplace (MappingIt) ;
189
+ continue ;
214
190
}
215
- }
216
- }
217
-
218
- // Returns mappings by specified input action
219
- void UInputUtilsLibrary::GetMappingsInContextByAction (const UInputMappingContext* InInputContext, const UInputAction* ByInputAction, TArray<FEnhancedActionKeyMapping>& OutMappings)
220
- {
221
- if (!ensureMsgf (InInputContext, TEXT (" ASSERT: [%i] %s:\n 'InInputContext' is not valid!" ), __LINE__, *FString (__FUNCTION__))
222
- || !ensureMsgf (ByInputAction, TEXT (" ASSERT: [%i] %s:\n 'ByInputAction' is not valid!" ), __LINE__, *FString (__FUNCTION__)))
223
- {
224
- return ;
225
- }
226
-
227
- if (!OutMappings.IsEmpty ())
228
- {
229
- OutMappings.Empty ();
230
- }
231
191
232
- TArray<FEnhancedActionKeyMapping> AllMappings;
233
- GetAllMappingsInContext (InInputContext, /* out*/ AllMappings);
234
- for (const FEnhancedActionKeyMapping& MappingIt : AllMappings)
235
- {
236
- if (MappingIt.Action == ByInputAction)
192
+ const FPlayerKeyMapping* FoundMapping = EnhancedInputUserSettings->FindCurrentMappingForSlot (MappingIt.GetMappingName (), EPlayerMappableKeySlot::First);
193
+ if (!FoundMapping)
237
194
{
238
- OutMappings.Emplace (MappingIt);
195
+ // The key is mappable, but it's not even registered in Enhanced Input User Settings (SetAllMappingsRegisteredInContext is not called)
196
+ continue ;
239
197
}
198
+
199
+ FPlayerKeyMapping RemappedMapping = *FoundMapping;
200
+ OutMappings.Emplace (MoveTemp (RemappedMapping));
240
201
}
241
202
}
242
203
243
204
// Returns true if specified key is mapped to given input context
244
- bool UInputUtilsLibrary::IsMappedKeyInContext (const FKey& Key, const UInputMappingContext* InInputContext)
205
+ bool UInputUtilsLibrary::IsMappedKeyInContext (const UObject* WorldContext, const FKey& Key, const UInputMappingContext* InInputContext)
245
206
{
246
- if (!ensureMsgf (InInputContext, TEXT (" ASSERT: [%i] %s:\n 'InInputContext' is not valid!" ), __LINE__, *FString (__FUNCTION__)))
207
+ const UEnhancedInputLocalPlayerSubsystem* InputSubsystem = GetEnhancedInputSubsystem (WorldContext);
208
+ const UEnhancedInputUserSettings* EnhancedInputUserSettings = InputSubsystem ? InputSubsystem->GetUserSettings () : nullptr ;
209
+ if (!ensureMsgf (EnhancedInputUserSettings, TEXT (" ASSERT: [%i] %hs:\n 'EnhancedInputUserSettings' is null, make sure 'Enable User Settings' is enabled in the Project Settings!" ), __LINE__, __FUNCTION__)
210
+ || !ensureMsgf (InInputContext, TEXT (" ASSERT: [%i] %hs:\n 'InInputContext' is not valid!" ), __LINE__, __FUNCTION__))
247
211
{
248
212
return false ;
249
213
}
250
214
251
- TArray<FEnhancedActionKeyMapping > AllMappings;
252
- GetAllMappingsInContext (InInputContext, /* out*/ AllMappings);
253
- return AllMappings.ContainsByPredicate ([&Key](const FEnhancedActionKeyMapping & MappingIt)
215
+ TArray<FPlayerKeyMapping > AllMappings;
216
+ GetAllMappingsInContext (WorldContext, InInputContext, /* out*/ AllMappings);
217
+ return AllMappings.ContainsByPredicate ([&Key](const FPlayerKeyMapping & MappingIt)
254
218
{
255
- return MappingIt.Key == Key;
219
+ return MappingIt.GetCurrentKey () == Key;
256
220
});
257
221
}
258
222
259
223
// Unmap previous key and map new one
260
- bool UInputUtilsLibrary::RemapKeyInContext (UInputMappingContext* InInputContext, const UInputAction* ByInputAction, const FKey& PrevKey, const FKey& NewKey)
224
+ bool UInputUtilsLibrary::RemapKeyInContext (const UObject* WorldContextObject, const UInputMappingContext* InInputContext, const UInputAction* ByInputAction, const FKey& PrevKey, const FKey& NewKey)
261
225
{
262
226
if (!ensureMsgf (InInputContext, TEXT (" ASSERT: 'InInputContext' is not valid" ))
263
227
|| !ensureMsgf (ByInputAction, TEXT (" ASSERT: [%i] %s:\n 'ByInputAction' is not valid!" ), __LINE__, *FString (__FUNCTION__))
264
228
|| NewKey == PrevKey
265
- || IsMappedKeyInContext (NewKey, InInputContext))
229
+ || IsMappedKeyInContext (WorldContextObject, NewKey, InInputContext))
230
+ {
231
+ return false ;
232
+ }
233
+
234
+ UEnhancedInputLocalPlayerSubsystem* InputSubsystem = GetEnhancedInputSubsystem (WorldContextObject);
235
+ UEnhancedInputUserSettings* EnhancedInputUserSettings = InputSubsystem ? InputSubsystem->GetUserSettings () : nullptr ;
236
+ if (!ensureMsgf (EnhancedInputUserSettings, TEXT (" ASSERT: [%i] %hs:\n 'EnhancedInputUserSettings' is null, make sure 'Enable User Settings' is enabled in the Project Settings!" ), __LINE__, __FUNCTION__))
266
237
{
267
238
return false ;
268
239
}
@@ -271,34 +242,55 @@ bool UInputUtilsLibrary::RemapKeyInContext(UInputMappingContext* InInputContext,
271
242
const TArray<FEnhancedActionKeyMapping>& AllMappings = InInputContext->GetMappings ();
272
243
for (const FEnhancedActionKeyMapping& MappingIt : AllMappings)
273
244
{
274
- if (MappingIt.Action == ByInputAction
275
- && MappingIt.Key == PrevKey)
245
+ if (MappingIt.Action != ByInputAction)
276
246
{
277
- InInputContext->UnmapKey (ByInputAction, PrevKey);
278
- InInputContext->MapKey (ByInputAction, NewKey);
279
- bRemapped = true ;
280
- break ;
247
+ continue ;
281
248
}
249
+
250
+ FMapPlayerKeyArgs Args;
251
+ Args.MappingName = MappingIt.GetMappingName ();
252
+ Args.Slot = EPlayerMappableKeySlot::First;
253
+ Args.NewKey = NewKey;
254
+ Args.bCreateMatchingSlotIfNeeded = true ;
255
+
256
+ FGameplayTagContainer FailureReason;
257
+ EnhancedInputUserSettings->UnMapPlayerKey (Args, FailureReason);
258
+
259
+ EnhancedInputUserSettings->MapPlayerKey (Args, FailureReason);
260
+ bRemapped = FailureReason.IsEmpty ();
261
+
262
+ break ;
282
263
}
283
264
284
265
if (!bRemapped)
285
266
{
286
267
return false ;
287
268
}
288
269
289
- if (CanSaveMappingsInConfig ())
290
- {
291
- UGameplayUtilsLibrary::SaveConfig (InInputContext);
292
- }
270
+ InputSubsystem->RequestRebuildControlMappings ();
271
+ EnhancedInputUserSettings->ApplySettings ();
272
+ EnhancedInputUserSettings->AsyncSaveSettings ();
293
273
294
274
return true ;
295
275
}
296
276
297
- // Unmap previous key and map new one
298
- bool UInputUtilsLibrary::RemapKeyInContext (const UInputMappingContext* InInputContext, const FEnhancedActionKeyMapping& InMapping , const FKey& NewKey )
277
+ // Register all mappings in the specified contexts
278
+ void UInputUtilsLibrary::SetAllMappingsRegisteredInContext (const UObject* WorldContext, bool bRegister , const UInputMappingContext* InInputContext )
299
279
{
300
- UInputMappingContext* ContextToRemap = const_cast <UInputMappingContext*>(InInputContext);
301
- return RemapKeyInContext (ContextToRemap, InMapping.Action , InMapping.Key , NewKey);
280
+ UEnhancedInputUserSettings* EnhancedInputUserSettings = GetEnhancedInputUserSettings (WorldContext);
281
+ if (!ensureMsgf (EnhancedInputUserSettings, TEXT (" ASSERT: [%i] %hs:\n 'EnhancedInputUserSettings' is null, make sure 'Enable User Settings' is enabled in the Project Settings!" ), __LINE__, __FUNCTION__))
282
+ {
283
+ return ;
284
+ }
285
+
286
+ if (bRegister)
287
+ {
288
+ EnhancedInputUserSettings->RegisterInputMappingContext (InInputContext);
289
+ }
290
+ else
291
+ {
292
+ EnhancedInputUserSettings->UnregisterInputMappingContext (InInputContext);
293
+ }
302
294
}
303
295
304
296
/* ********************************************************************************************
@@ -322,11 +314,3 @@ APlayerController* UInputUtilsLibrary::GetLocalPlayerController(const UObject* W
322
314
323
315
return nullptr ;
324
316
}
325
-
326
- // Returns true if remapped key is allowed to be saved in config
327
- bool UInputUtilsLibrary::CanSaveMappingsInConfig ()
328
- {
329
- // Always return true in cook since there remaps should be saved into config file and taken there.
330
- // We don't want to save remaps in Editor, it gets serialised right into asset
331
- return !UUtilsLibrary::IsEditor ();
332
- }
0 commit comments