Since your goal is to capture keyboard input and trigger something if the player types in a specific sequence of letters, I suggest trying to use the InputKey function in the APlayerController class.
This function is virtual, meaning you can override it in your custom player controller, and it will be called up (presumably) every time the player presses a keyboard key. (I say ‘presumably’ because I’ve never used this function myself, and I won’t get a chance to test it within the next few hours, so I’m just crossing my fingers for now.)
The function’s signature provides an FKey
parameter that you can use to identify which key was pressed. The basic idea is to log which keys the player presses, storing the results in a string, and checking the string to see if it matches the desired sequence (e.g. “ezgame”). After a couple seconds of no keyboard input, the string will be cleared, giving the player another chance to try to type the sequence correctly.
One possible implementation might look like this:
(This goes in your player controller .cpp file. Assume you have an FString variable called ‘CodeSequence’ which you’ll use to keep track of what the player has ‘typed in’ so far.)
bool InputKey(FKey Key, EInputEvent EventType, float AmountDepressed, bool bGamepad)
{
// Only bother with presses (not releases) and don't worry about mouse button events
if (InputType == EInputEvent::IE_Pressed && Key.IsMouseButton() == false)
{
// Clear the CodeSequence string if the last key press was more than 2 seconds ago
ResetExpiredCodeSequence(); // in case it's not clear, this is another custom function
// float TimeOfLastKeyPress is a float variable that you'll also set up in your Player Controller class
TimeOfLastKeyPress = GetGameTimeSinceCreation(); // set the time (now) for the current key press; this is used by ResetExpiredCodeSequence(), above
// Add the pressed key's "character" to the CodeSequence (by getting the key's string representation)
CodeSequence += Key.ToString();
// Call a custom function that compares the sequence to a list of your matching 'codes'
CheckCodeSequence();
}
// Return a bool by calling the Super version of this function
return Super::InputKey(Key, EventType, AmountDepressed, bGamepad);
}
As shown above, you’ll also need a couple additional functions to get things working. Such as:
void ResetExpiredCodeSequence()
{
// Find out how many seconds has passed since the last key press
float TimeSinceLastKeyPress = GetGameTimeSinceCreation() - TimeOfLastKeyPress;
bool bSequenceExpired = TimeSinceLastKeyPress > 2.0f; // arbitrarily choosing 2 seconds for this example
if (bSequenceExpired)
{
// If more than 2 seconds has passed since the last key press, reset the string; otherwise, don't do anything
CodeSequence = ""; // reset the string back to a blank, empty string
}
}
And finally, something to compare to your ‘matching’ sequence strings:
void CheckCodeSequence()
{
if (CodeSequence == "EZGAME")
{
// Do something to handle this match, e.g. spawn your actor(s)
}
else if (CodeSequence == "EXAMPLE2")
{
// Just another example to show that you can handle more than one match possibility
}
// etc.
}
Note that I’m using exclusively all caps in the above example. You don’t have to do that — you could use all lowercase — but the important thing is that you remain consistent.
As I said above, I don’t think I’ve used the InputKey
function yet myself, and I’ve certainly not yet attempted to get a ‘cheat code’ input system like this working before myself. So maybe this won’t work exactly as I’ve written it. But hopefully it moves you (and anyone else who may find it) further in the right direction.