Poll inputs outside of game logic tick

This commit is contained in:
Kevin Poretti 2023-11-10 10:05:16 -05:00
parent b62a8cebb6
commit 2f22223776
3 changed files with 47 additions and 6 deletions

View File

@ -1,7 +1,12 @@
// Project Sword & Gun Copyright Kevin Poretti
// FF includes
#include "Input/FFPlayerController.h"
#include "GameplayFramework/FFGameState.h"
// UE includes
#include "Kismet/GameplayStatics.h"
void AFFGameState::OnFixedTick(float OneTick)
{
}
@ -11,15 +16,50 @@ void AFFGameState::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
/*
* TODO: I want to reinvestigate how we're collecting and applying inputs. I seem to keep getting
* weird timing issues due to how Unreal collects and informs the game of inputs through function
* callbacks rather than some mechanism where we can poll the state of various actions/axes when
* it comes time to update. The investigation should be two-fold:
*
* 1 - is there any alternative ways of using the EnhancedInputComponent but polling for inputs
* rather than this whole callback system, so when it is time to tick the game state we can just
* do something like a bool bIsJumpPressed = GetActionValue("Jump") for all inputs and axes
* we need to collect?
*
* 2 - if there isn't any polling mechanism in the EnhancedInputComponent, how can we work around
* that and what are some of the things we have to keep in mind? What happens when the Unreal tick
* rate is slower than the game tick rate? Do we just apply the current input to multiple game ticks?
* What about when Unreal's tick rate is faster than the game? Would that make the game feel
* unresponsive i.e. feel like inputs are getting dropped?
*
* 3 - would like to know more about EnhancedInputComponent and inputs in Unreal in general as well.
* Are inputs collected in a separate thread? How does unreal determine when to call any input callbacks
* you've registered with the input component?
*/
// Get inputs
AFFPlayerController* PC = Cast<AFFPlayerController>(UGameplayStatics::GetPlayerController(GetWorld(), 0));
if(!PC)
{
UE_LOG(LogTemp, Warning, TEXT("Could not get a local player controller so no inputs could be collected"));
return;
}
PC->ModifyRawInput();
// Run anything game logic related at a fixed tick rate
// TODO: Interpolate between prev and current game state if there is time left in accumulator
AccumulatedTime += DeltaSeconds;
while(AccumulatedTime > ONE_TICK)
{
PC->AddCurrentInputToBuffer();
OnFixedTick(ONE_TICK);
AccumulatedTime -= ONE_TICK;
CurrentTick++;
}
PC->ConsumeMoveInput();
}

View File

@ -49,7 +49,7 @@ FVector AFFPlayerController::GetInputAsWorldDirection() const
}
void AFFPlayerController::FixedTick(float OneFrame)
void AFFPlayerController::AddCurrentInputToBuffer()
{
//UnacknowledgedInputs.Push(RawInput);
InputBuffer->AddInput(ModifiedInput);

View File

@ -20,7 +20,7 @@
* unacknowledged inputs to a remote client or server for processing.
*/
UCLASS()
class UNREALFIGHTINGFRAMEWORK_API AFFPlayerController : public APlayerController, public IFFSystemInterface, public IFFStateOwnerInterface
class UNREALFIGHTINGFRAMEWORK_API AFFPlayerController : public APlayerController, public IFFStateOwnerInterface
{
GENERATED_BODY()
@ -54,15 +54,16 @@ public:
UFUNCTION(BlueprintPure)
bool HasMoveInput();
// TODO: document
void ConsumeMoveInput();
// TODO: document
FVector GetInputAsWorldDirection() const;
// IFFSystemInterface interface
virtual void FixedTick(float OneFrame) override;
// End of IFFSystemInterface
// TODO: document
void AddCurrentInputToBuffer();
// IFFStateOwnerInterface
// IFFStateOwnerInterface
UFUNCTION()
virtual bool CheckInputSequence(const FFFInputSequence& InInputSequence) override;