Detect button press/release and disable inputs when they trigger a sequence
This commit is contained in:
		
							parent
							
								
									9f16901de6
								
							
						
					
					
						commit
						b8fa341503
					
				@ -12,28 +12,54 @@ void UFFInputBufferComponent::AddInput(const FFFInputState& InputState)
 | 
				
			|||||||
	InputBuffer.ForcePush(InputState);
 | 
						InputBuffer.ForcePush(InputState);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool UFFInputBufferComponent::CheckInputSequence(const FFFInputCondition& InputCondition)
 | 
					bool UFFInputBufferComponent::CheckInputSequence(const FFFInputSequence& InputSequence)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int CondIdx = InputCondition.Sequence.Num() - 1;
 | 
					    int CondIdx = InputSequence.Sequence.Num() - 1;
 | 
				
			||||||
    int FramesSinceValidInput = 0;
 | 
					    int FramesSinceValidInput = 0;
 | 
				
			||||||
    for(int InpIdx = 0; InpIdx < InputBuffer.Num(); InpIdx++)
 | 
					    for(int InpIdx = 0; InpIdx < InputBuffer.Num() - 1; InpIdx++)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        int32 CurrCondition = InputCondition.Sequence[CondIdx].Buttons;
 | 
					        int32 RequiredButtons = InputSequence.Sequence[CondIdx].RequiredButtons;
 | 
				
			||||||
        int32 ThisInput = InputBuffer[InpIdx].Buttons;
 | 
					        EFFButtonState RequiredButtonState = InputSequence.Sequence[CondIdx].RequiredButtonState;
 | 
				
			||||||
        if(ThisInput & CurrCondition)
 | 
					        int32 PrevInput = InputBuffer[InpIdx + 1].Buttons;
 | 
				
			||||||
 | 
					        int32 CurrInput = InputBuffer[InpIdx].Buttons;
 | 
				
			||||||
 | 
					        int32 PrevDisable = InputBuffer[InpIdx + 1].DisabledButtons;
 | 
				
			||||||
 | 
					        int32 CurrDisable = InputBuffer[InpIdx].DisabledButtons;
 | 
				
			||||||
 | 
					        switch (RequiredButtonState)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            CondIdx--;
 | 
					            case EFFButtonState::BTNS_Pressed:
 | 
				
			||||||
            FramesSinceValidInput = 0;
 | 
					                if(!(PrevInput & RequiredButtons | PrevDisable) && 
 | 
				
			||||||
 | 
					                   CurrInput & RequiredButtons & ~CurrDisable)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CondIdx--;
 | 
				
			||||||
 | 
					                    FramesSinceValidInput = 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case EFFButtonState::BTNS_Released:
 | 
				
			||||||
 | 
					                if(PrevInput & RequiredButtons & ~PrevDisable &&
 | 
				
			||||||
 | 
					                   !(CurrInput & RequiredButtons | CurrDisable))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CondIdx--;
 | 
				
			||||||
 | 
					                    FramesSinceValidInput = 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            // TODO: implement button held condition
 | 
				
			||||||
 | 
					            /*
 | 
				
			||||||
 | 
					            case EFFButtonState::BTNS_Held:
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            */
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // All conditions were met
 | 
					        // All conditions were met
 | 
				
			||||||
        if(CondIdx == -1)
 | 
					        if(CondIdx == -1)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            // disable inputs that triggered the sequence
 | 
				
			||||||
 | 
					            InputBuffer[InpIdx].DisabledButtons |= InputBuffer[InpIdx].Buttons;
 | 
				
			||||||
 | 
					            InputBuffer[InpIdx + 1].DisabledButtons |= InputBuffer[InpIdx + 1].Buttons;
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        FramesSinceValidInput++;
 | 
					        FramesSinceValidInput++;
 | 
				
			||||||
        if(FramesSinceValidInput > InputCondition.Lenience)
 | 
					        if(FramesSinceValidInput > InputSequence.Sequence[CondIdx].Lenience)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "FFInputBufferComponent.generated.h"
 | 
					#include "FFInputBufferComponent.generated.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UENUM(BlueprintType)
 | 
				
			||||||
 | 
					enum class EFFButtonState : uint8
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    BTNS_Pressed		UMETA(DisplayName="Pressed"),
 | 
				
			||||||
 | 
						BTNS_Released		UMETA(DisplayName="Released"),
 | 
				
			||||||
 | 
						//BTNS_Held			UMETA(DisplayName="Held"),
 | 
				
			||||||
 | 
						BTNS_MAX			UMETA(Hidden)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *	Struct representing the state of a player's inputs for one frame
 | 
					 *	Struct representing the state of a player's inputs for one frame
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@ -24,6 +33,7 @@ struct FFFInputState
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	UPROPERTY(EditAnywhere, Meta = (Bitmask))
 | 
						UPROPERTY(EditAnywhere, Meta = (Bitmask))
 | 
				
			||||||
	int32		Buttons;
 | 
						int32		Buttons;
 | 
				
			||||||
 | 
						int32		DisabledButtons;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
USTRUCT(BlueprintType)
 | 
					USTRUCT(BlueprintType)
 | 
				
			||||||
@ -31,13 +41,27 @@ struct FFFInputCondition
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    GENERATED_BODY()
 | 
					    GENERATED_BODY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    UPROPERTY(EditAnywhere)
 | 
						// Buttons required for this specific condition to be valid
 | 
				
			||||||
	TArray<FFFInputState> Sequence;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	UPROPERTY(EditAnywhere)
 | 
						UPROPERTY(EditAnywhere)
 | 
				
			||||||
 | 
						int32 RequiredButtons;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The button state required for condition to be valid i.e. pressed or released
 | 
				
			||||||
 | 
						UPROPERTY(EditAnywhere)
 | 
				
			||||||
 | 
						EFFButtonState RequiredButtonState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    UPROPERTY(EditAnywhere)
 | 
				
			||||||
	int32 Lenience;
 | 
						int32 Lenience;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					USTRUCT(BlueprintType)
 | 
				
			||||||
 | 
					struct FFFInputSequence
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GENERATED_BODY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    UPROPERTY(EditAnywhere)
 | 
				
			||||||
 | 
						TArray<FFFInputCondition> Sequence;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
 | 
					UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
 | 
				
			||||||
class UNREALFIGHTINGFRAMEWORK_API UFFInputBufferComponent : public UActorComponent
 | 
					class UNREALFIGHTINGFRAMEWORK_API UFFInputBufferComponent : public UActorComponent
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -48,7 +72,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	void AddInput(const FFFInputState& InputState);
 | 
						void AddInput(const FFFInputState& InputState);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool CheckInputSequence(const FFFInputCondition& InputCondition);
 | 
						bool CheckInputSequence(const FFFInputSequence& InputSequence);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
	/** The underlying buffer data structure for holding past input states */
 | 
						/** The underlying buffer data structure for holding past input states */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user