Skip to content

Instantly share code, notes, and snippets.

@MilkyEngineer
Created March 3, 2021 06:00
Show Gist options
  • Save MilkyEngineer/391067672d2e6e50651ed53b9f019f14 to your computer and use it in GitHub Desktop.
Save MilkyEngineer/391067672d2e6e50651ed53b9f019f14 to your computer and use it in GitHub Desktop.
UE4: Reset action mapping to defaults
// Copyright Epic Games, Inc. All Rights Reserved.
#include "FunctionLibrary.h"
#include "GameFramework/InputSettings.h"
bool UFunctionLibrary::ReloadConfigProperty(UObject* Object, FName PropertyName, UClass* Class)
{
if (Object == NULL)
{
return false;
}
if (Class == NULL)
{
Class = Object->GetClass();
}
// Temporarily load a fresh version of the ini file, but also force the reload from disk!
FConfigFile Config;
if (!FConfigCacheIni::LoadLocalIniFile(Config, *Class->ClassConfigName.ToString(), true, Object->GetConfigOverridePlatform(), true))
{
return false;
}
// Access the Action Mappings property
FProperty* Property = Class->FindPropertyByName(*PropertyName.ToString());
FConfigSection* ClassSection = Config.Find(*Class->GetPathName());
if (Property && ClassSection)
{
FString Key = Property->GetName();
// Stripped these sections from UObject::LoadConfig
if (FArrayProperty* ArrayProperty = CastField<FArrayProperty>(Property))
{
// Handle an array...
TArray<FConfigValue> List;
const FName KeyName(*Key, FNAME_Find);
ClassSection->MultiFind(KeyName, List);
FScriptArrayHelper_InContainer ArrayHelper(ArrayProperty, Object);
ArrayHelper.EmptyAndAddValues(List.Num());
for (int32 i = List.Num() - 1, c = 0; i >= 0; i--, c++)
{
ArrayProperty->Inner->ImportText(*List[i].GetValue(), ArrayHelper.GetRawPtr(c), PPF_None, Object);
}
}
else
{
// Handle all other properties...
for (int32 i = 0; i < Property->ArrayDim; i++)
{
if (Property->ArrayDim != 1)
{
Key = FString::Printf(TEXT("%s[%i]"), *Property->GetName(), i);
}
if (const FConfigValue* ConfigValue = ClassSection->Find(*Key))
{
Property->ImportText(*ConfigValue->GetValue(), Property->ContainerPtrToValuePtr<uint8>(Object, i), PPF_None, Object);
}
}
}
Object->PostReloadConfig(Property);
return true;
}
return false;
}
void UFunctionLibrary::ResetActionMapping(UInputSettings* InputSettings, FName ActionName)
{
check(InputSettings != NULL);
// Save the other mappings so that we can add them back after the config load overrides everything
TArray<FInputActionKeyMapping> CurrentMappings = InputSettings->GetActionMappings();
// Make sure to strip out the actions we want to reload
CurrentMappings.RemoveAll([ActionName](const FInputActionKeyMapping& Mapping)
{
return Mapping.ActionName == ActionName;
});
UFunctionLibrary::ReloadConfigProperty(InputSettings, "ActionMappings", UInputSettings::StaticClass());
TArray<FInputActionKeyMapping> ReloadedMappings = InputSettings->GetActionMappings();
// We've loaded the old action mappings, so lets remove anything that isn't our action we want...
for (const FInputActionKeyMapping& Mapping : ReloadedMappings)
{
if (Mapping.ActionName != ActionName)
{
InputSettings->RemoveActionMapping(Mapping, false);
}
}
// ... and add back in all of the other old actions...
for (const FInputActionKeyMapping& Mapping : CurrentMappings)
{
InputSettings->AddActionMapping(Mapping);
}
InputSettings->ForceRebuildKeymaps();
}
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
class UInputSettings;
#include "Kismet/BlueprintFunctionLibrary.h"
#include "FunctionLibrary.generated.h"
UCLASS(MinimalAPI)
class UFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
/**
* Resets the config property to the defaults (i.e. project defaults)
*
* @param Object The object to reload the config property into
* @param PropertyName The property to reload
* @param Class The class to load properties from, will use Object's class if NULL
*
* @return true if property reload was successful
*/
static bool ReloadConfigProperty(UObject* Object, FName PropertyName, UClass* Class = NULL);
/**
* Effectively resets an action mapping of a particular name to project defaults. Will force a rebuild of keymaps.
*
* @param InputSettings The input settings object, should be retrieved via UInputSettings::GetInputSettings
* @param ActionName The action to reset to default
*/
UFUNCTION(BlueprintCallable, Category = InputSettings)
static void ResetActionMapping(UInputSettings* InputSettings, FName ActionName);
};
@MilkyEngineer
Copy link
Author

MilkyEngineer commented Mar 3, 2021

For example, in the Third Person template, I can remove the spacebar Jump action, and then reset the entire set of Jump action mappings back to default:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment