在windows的游戏控制器里看,数据是连贯的,但是用rawinput看,数据平均分成了两部分,静止的时候是0.5,推到中间是1,再继续往前推立刻就变成0了,然后推到头又变成0.5
请问怎么样让它是一段连贯的数据
在windows的游戏控制器里看,数据是连贯的,但是用rawinput看,数据平均分成了两部分,静止的时候是0.5,推到中间是1,再继续往前推立刻就变成0了,然后推到头又变成0.5
请问怎么样让它是一段连贯的数据
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这可能是由于UE4对输入设备的输入数据处理方式不同于Windows游戏控制器的原因导致的。UE4在处理输入数据时会进行一些中间处理,使得输入的轴数据呈现出了分段的状态。
要解决这个问题,可以通过在UE4中注册轴事件并手动处理RawInput数据来获得连续的轴数据。具体步骤如下:
首先,使用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)
{
// 处理注册失败的情况
}
在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);
}
最后,在项目中找到输入类并重写OnJoystickAxis事件以获取连续的轴数据。
void AMyPlayer::OnJoystickAxis(float X, float Y)
{
// 可以直接使用手柄的X和Y轴数据
// 处理连续的轴数据
}
使用这种方式可以手动处理RawInput数据并获得连续的轴数据,从而解决分段的问题。
如果我的回答解决了您的问题,请采纳!