問題描述: 在角色行走的過程中(由方向鍵控制),觸發了某些機制,角色不再受玩家控制(比如觸發了簡單的對話,需要設置下角色位置然後站立等)等在對話完成返回後,發現角色一直在行走,即使你沒有按任何的按鍵。
問題原因: 觸發某些機制後,輸入控制轉交給了UI系統或者其他系統,角色本身的輸入系統沒有收到原來的KeyReleased的消息,等到控制權回到角色的時候,由於行走的按鈕狀態仍然處於KeyDown的狀態,所以仍然會行走。
解決方案: 觸發機制前調用APlayerController::FlushPressedKeys函數,該函數會調用內部的UPlayerInput::FlushPressedKeys,該函數會向所有狀態爲Down的按鍵模擬發送一次Released的事件,通知這些按鍵已經釋放了。
void UPlayerInput::FlushPressedKeys()
{
APlayerController* PlayerController = GetOuterAPlayerController();
ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PlayerController->Player);
if ( LocalPlayer != NULL )
{
TArray<FKey> PressedKeys;
for (TMap<FKey,FKeyState>::TIterator It(KeyStateMap); It; ++It)
{
const FKeyState& KeyState = It.Value();
if (KeyState.bDown)
{
PressedKeys.Add(It.Key());
}
}
// we may have gotten here as a result of executing an input bind. in order to ensure that the simulated IE_Released events
// we're about to fire are actually propagated to the game, we need to clear the bExecutingBindCommand flag
if ( PressedKeys.Num() > 0 )
{
bExecutingBindCommand = false;
for ( int32 KeyIndex = 0; KeyIndex < PressedKeys.Num(); KeyIndex++ )
{
FKey& Key = PressedKeys[KeyIndex];
InputKey(Key, IE_Released, 0, Key.IsGamepadKey());
}
}
}
//......
}