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);
   }
}
posted @ 2022-05-14 12:33  AFK_W  阅读(598)  评论(0)    收藏  举报