Hello there, I want to implement something similar to super smash brothers’ smash attacks, where by smashing (aka turning a stick very fast in one direction) the analog stick and pressing the attack button you perform a stronger attack.
My idea of implementing this is having some sort of delta-time based value that I can extract from the difference of the stick’s position since last frame.
Anyone has any tips on how to do this?
Finally figured this out, here’s how I did it, it’s for the right axis, but you can adapt it to the left one
I added the following values to my pawn:
float axisTapWindow = 0.05f; //the time between letting go of neutral and the minimum tap for the move to be considered a tap
float axisTapMinimum = 0.5f; //the minimum axis value required for it to be considered a tap
float axisTapAttackWindow = 0.03f; //the time the user has after the tap to perform an attack
bool wasRightAxisNeutralLastTick = true; //if the axis was at 0 last tick
bool isTappingRightAxis = false; //if the user is tapping the right axis
Here’s the code in the controller:
void ABorealController::MoveRight(float Value)
{
/*UpdateChar();*/
// Apply the input to the character motion
//AddMovementInput(FVector(1.0f, 0.0f, 0.0f), Value);
ABorealCharacter *character = Cast<ABorealCharacter>(GetPawn());
if (GetWorld())
{
if (character != NULL)
{
if (Value == 0)
{
character->wasRightAxisNeutralLastTick = true;
}
if (character->wasRightAxisNeutralLastTick)
{
character->wasRightAxisNeutralLastTick = false;
GetWorld()->GetTimerManager().SetTimer(RightAxisTapTimeoutHandle, this, &ABorealController::RightAxisTapTimeout, character->axisTapWindow, false);
}
if (Value > character->axisTapMinimum || Value < (character->axisTapMinimum*-1))
{
if (GetWorld()->GetTimerManager().IsTimerActive(RightAxisTapTimeoutHandle))
{
GetWorld()->GetTimerManager().ClearTimer(RightAxisTapTimeoutHandle);
GetWorld()->GetTimerManager().SetTimer(RightAxisAttackTimeoutHandle, this, &ABorealController::RightAxisAttackTimeout, character->axisTapAttackWindow, false);
character->isTappingRightAxis = true;
UE_LOG(LogTemp, Warning, TEXT("Tapped right"));
}
}
}
}
}
void ABorealController::RightAxisTapTimeout()
{
return;
}
void ABorealController::RightAxisAttackTimeout()
{
ABorealCharacter *character = Cast<ABorealCharacter>(GetPawn());
if (character != NULL)
{
character->isTappingRightAxis = false;
}
}
Header:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "GameFramework/PlayerController.h"
#include "BorealController.generated.h"
/**
*
*/
UCLASS()
class BOREAL_API ABorealController : public APlayerController
{
GENERATED_BODY()
protected:
FTimerHandle RightAxisTapTimeoutHandle;
FTimerHandle UpAxisTapTimeoutHandle;
FTimerHandle RightAxisAttackTimeoutHandle;
FTimerHandle UpAxisAttackTimeoutHandle;
public:
void RightAxisTapTimeout();
void RightAxisAttackTimeout();
};