问题描述: 在角色行走的过程中(由方向键控制),触发了某些机制,角色不再受玩家控制(比如触发了简单的对话,需要设置下角色位置然后站立等)等在对话完成返回后,发现角色一直在行走,即使你没有按任何的按键。
问题原因: 触发某些机制后,输入控制转交给了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());
}
}
}
//......
}