zzzl 2023-04-21 21:55 采纳率: 0%
浏览 31
已结题

ue4用rawinput获取的轴数据被分段了

在windows的游戏控制器里看,数据是连贯的,但是用rawinput看,数据平均分成了两部分,静止的时候是0.5,推到中间是1,再继续往前推立刻就变成0了,然后推到头又变成0.5

请问怎么样让它是一段连贯的数据

  • 写回答

3条回答 默认 最新

  • 极客智能体-在线 2023-04-22 15:19
    关注

    以下答案由GPT-3.5大模型与博主波罗歌共同编写:
    这可能是由于UE4对输入设备的输入数据处理方式不同于Windows游戏控制器的原因导致的。UE4在处理输入数据时会进行一些中间处理,使得输入的轴数据呈现出了分段的状态。

    要解决这个问题,可以通过在UE4中注册轴事件并手动处理RawInput数据来获得连续的轴数据。具体步骤如下:

    1. 首先,使用RawInput API注册输入设备并获取其句柄。

      RAWINPUTDEVICE rid = {};
      rid.usUsagePage = 0x01;
      rid.usUsage = 0x04; // joystick
      rid.dwFlags = RIDEV_INPUTSINK;
      rid.hwndTarget = hWnd; //窗口句柄,可以从UE4获取
      if (RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == FALSE)
      {
          // 处理注册失败的情况
      }
      
    2. 在UE4的输入类中创建一个轴事件,并将其绑定到RawInput轴的通知函数中。在通知函数中将RawInput数据传递给轴事件以手动处理数据。

      // 在输入类中定义一个轴事件
      UFUNCTION(BlueprintImplementableEvent, Category = "Input")
      void OnJoystickAxis(float X, float Y);
      
      // RawInput轴通知函数
      LRESULT WINAPI RawInputAxis(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
      {
          // 使用GetRawInputData()获取输入数据
          RAWINPUT rawInput;
          UINT size = sizeof(RAWINPUT);
          if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &rawInput, &size, sizeof(RAWINPUTHEADER)) != UINT(-1))
          {
              if (rawInput.header.dwType == RIM_TYPEHID && rawInput.hid.dwSizeHid >= sizeof(HIDP_VALUE_CAPS))
              {
                  HIDP_VALUE_CAPS valueCaps;
                  USHORT numValues = 0;
                  PHIDP_PREPARSED_DATA pData = nullptr;
                  if (HidP_GetPreparsedData(rawInput.hid.bRawData, &pData) == HIDP_STATUS_SUCCESS)
                  {
                      HidP_GetValueCaps(HidP_Input, &valueCaps, &numValues, pData);
      
                      if (numValues > 0)
                      {
                          HIDP_VALUE_CAPS* pValueCaps = new HIDP_VALUE_CAPS[numValues];
                          if (HidP_GetValueCaps(HidP_Input, pValueCaps, &numValues, pData) == HIDP_STATUS_SUCCESS)
                          {
                              // 解析轴数据
                              for (USHORT i = 0; i < numValues; ++i)
                              {
                                  if (HidP_IsAxis(pValueCaps[i].UsagePage, pValueCaps[i].LogicalMin, pValueCaps[i].LogicalMax))
                                  {
                                      LONG value = 0;
                                      if (HidP_GetUsageValue(HidP_Input, pValueCaps[i].UsagePage, 0, pValueCaps[i].NotRange.Usage, &value, pData, rawInput.hid.bRawData, rawInput.hid.dwSizeHid) == HIDP_STATUS_SUCCESS)
                                      {
                                          float axisValue = (value - pValueCaps[i].LogicalMin) / static_cast<float>(pValueCaps[i].LogicalMax - pValueCaps[i].LogicalMin) * 2.f - 1.f;
      
                                          // 触发轴事件
                                          UGameViewportClient* viewport = GEngine->GameViewport;
                                          if (viewport)
                                          {
                                              APlayerController* controller = viewport->GetWorld()->GetFirstPlayerController();
                                              if (controller)
                                              {
                                                  controller->ProcessEvent(controller->FindFunctionChecked("OnJoystickAxis"), &axisValue, 1);
                                              }
                                          }
                                      }
                                  }
                              }
                          }
                          delete[] pValueCaps;
                      }
                      HidD_FreePreparsedData(pData);
                  }
              }
          }
      
          return DefWindowProc(hWnd, uMsg, wParam, lParam);
      }
      
    3. 最后,在项目中找到输入类并重写OnJoystickAxis事件以获取连续的轴数据。

      void AMyPlayer::OnJoystickAxis(float X, float Y)
      {
          // 可以直接使用手柄的X和Y轴数据
          // 处理连续的轴数据
      }
      

    使用这种方式可以手动处理RawInput数据并获得连续的轴数据,从而解决分段的问题。
    如果我的回答解决了您的问题,请采纳!

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月22日
  • 修改了问题 4月21日
  • 创建了问题 4月21日

悬赏问题

  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。