UEC++:设置系统——按键设置
准备:
1,一个用于放键盘按键以及设置的UMG,作用为:用于按照给定的规则创建显示按键修改的Widget
2,UserWidget存放单个的按键。作用:用于根据传进来的数据进行键盘修改的更新
3,一个存放提供给用户修改操作键的表单。作用:在创建单个Widget组件到UMG上时进行表单和实际项目上的操作进行对比。只允许表单上出现的操作可以提供给用户修改。
需求:实现表单提供的修改键值数据出现在UMG上
思路:1,在C++中创建一个结构体:FName(存放键值的操作名字,比如:Jump,MoveRight)
FText(存放一个描述,用于显示在Widget上的按键作用描述)
FKey(用于存放按键的键值)
bool(用于区分是轴映射还是操作映射)
float(当为轴映射的时候,Scale的值为-1,1,还是0)

2,根据结构体创建一个表单,填写需要显示给用户的信息

3,在UMG中写代码逻辑:
1,读取表单数据。获得表单资源

2,获得表单数据进行存储
TArray<FKeySettingInfo*> KeyInfoArray;
KeyMapData->GetAllRows(TEXT("读取出错!"),KeyInfoArray);
3,通过遍历表单的数据,根据表单中是Scale的值进行分类为周映射和操作映射,并根据不同的映射走不同的项目的操作对比。并且要是操作映射,值对比FName的值是否相等。要是轴映射,对比FName和Scale的值是否相等。
TSubclassOf<UKeyBoardWidget> KeyWidgetClass = LoadClass<UKeyBoardWidget>(nullptr,TEXT("WidgetBlueprint'/Game/UI/Widget_KeyBoard.Widget_KeyBoard_C'"));
for(auto item:KeyInfoArray)
{
bool isValid = false;
FKey TargetKey;
//检测用户的按键
if (item->isAxis)
{
const TArray<FInputAxisKeyMapping> AxisArray = UInputSettings::GetInputSettings()->GetAxisMappings();
for (auto AxisItem:AxisArray)
{
if(AxisItem.AxisName == item->Name && AxisItem.Scale == item->MapScalce)
{
isValid = true;
TargetKey = AxisItem.Key;
break;
}
}
}else
{
//获得操作映射列表和轴映射列表
const TArray<FInputActionKeyMapping> ActionArray = UInputSettings::GetInputSettings()->GetActionMappings();
for (auto ActionItem:ActionArray)
{
if(ActionItem.ActionName == item->Name)
{
isValid = true;
TargetKey = ActionItem.Key;
break;
}
}
}
if(!isValid)
continue;
if(KeyWidgetClass)
{
auto KeyWidget = CreateWidget<UKeyBoardWidget>(GetOwningPlayer(),KeyWidgetClass);
if(KeyWidget)
{
KeyWidget->InitKeyInfo(item,TargetKey);
KeyVerticalBox->AddChild(KeyWidget);
//进行数据存储,用于后面的重复按键的检测
KeyArrays.Add(KeyWidget);
}
}
}
4,通过判断是否有对应表单的操作来创建Widget。Widget里面的信息初始化。
Widget中提供一个初始化的接口,接收一行表单的数据和实际项目操作的键值。并且将表单中的FTex和实际的操作键值显示出来。
需求:通过修改Widget上的按键,并且修改实际项目中的按键操作
思路:
1,检查修改的按键是否已经被使用,要是被使用或者修改后的按键和修改之前的按键是一样的。就不执行。
检查是否被用了,可以在UMG中将创建的Widget进行一个数值存储。遍历对比修改后的按键是否已经被用到了。
bool USettingSystemUserWidget::KeyhasUsed(FKey Key)
{
for (auto item:KeyArrays)
{
if(item->GetKey() == Key)
return true;
}
return false;
}
if(SelectedKey.Key == MyKey || Cast<ALegoHUD>(GetOwningPlayer()->GetHUD())->GetSettingSystemInstance()->KeyhasUsed(SelectedKey.Key))
{
KeySelector->SetSelectedKey(MyKey);
return;
}
2,修改按键,按照轴映射和操作映射进行不同的修改。由于项目的操作只能是删除和添加,没有修改。
if(Scale == 0)
{
FInputActionKeyMapping ActionKeyMapping;
ActionKeyMapping.Key = MyKey;
ActionKeyMapping.ActionName = MyName;
UInputSettings::GetInputSettings()->RemoveActionMapping(ActionKeyMapping,true);
ActionKeyMapping.Key = SelectedKey.Key;
MyKey = SelectedKey.Key;
UInputSettings::GetInputSettings()->AddActionMapping(ActionKeyMapping,true);
}else
{
FInputAxisKeyMapping AxisKeyMapping;
AxisKeyMapping.Key = MyKey;
AxisKeyMapping.AxisName = MyName;
AxisKeyMapping.Scale = Scale;
UInputSettings::GetInputSettings()->RemoveAxisMapping(AxisKeyMapping,true);
AxisKeyMapping.Key = SelectedKey.Key;
MyKey = SelectedKey.Key;
UInputSettings::GetInputSettings()->AddAxisMapping(AxisKeyMapping,true);
}
需求:增加一个一键恢复初始设置功能
思路:1,在Widget中初始化的时候存放一个默认值。并且对外有一个恢复默认设置的接口

2,接口的功能是,把显示全部该回去。其次是修改项目中的操作也改回。
void UKeyBoardWidget::Reset()
{
KeySelector->SetSelectedKey(DefaultKey);
ReviseKeyOption(DefaultKey);
}
void UKeyBoardWidget::ReviseKeyOption(FKey key)
{
if(Scale == 0)
{
FInputActionKeyMapping ActionKeyMapping;
ActionKeyMapping.Key = MyKey;
ActionKeyMapping.ActionName = MyName;
UInputSettings::GetInputSettings()->RemoveActionMapping(ActionKeyMapping,true);
ActionKeyMapping.Key = key;
MyKey = key;
UInputSettings::GetInputSettings()->AddActionMapping(ActionKeyMapping,true);
}else
{
FInputAxisKeyMapping AxisKeyMapping;
AxisKeyMapping.Key = MyKey;
AxisKeyMapping.AxisName = MyName;
AxisKeyMapping.Scale = Scale;
UInputSettings::GetInputSettings()->RemoveAxisMapping(AxisKeyMapping,true);
AxisKeyMapping.Key = key;
MyKey = key;
UInputSettings::GetInputSettings()->AddAxisMapping(AxisKeyMapping,true);
}
}

浙公网安备 33010602011771号