
[이득우의 언리얼 프로그래밍 Part2] 강의와 Unreal Engine 문서를 참고하여 공부한 내용입니다.
https://dev.epicgames.com/documentation/ko-kr/unreal-engine/enhanced-input-in-unreal-engine

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "EnhancedInput" });
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UInputMappingContext> mDefaultMappingContext;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UInputAction> mMoveAction;









void Move(const FInputActionValue& Value);
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
void AFQPlayerBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent);
EnhancedInputComponent->BindAction(mMoveAction, ETriggerEvent::Triggered, this, &AFQPlayerBase::Move);
}
void AFQPlayerBase::Move(const FInputActionValue& Value)
{
FVector2D MovementVector = Value.Get<FVector2D>();
UE_LOG(LogTemp, Warning, TEXT("MovementVector : %f, %f"), MovementVector.X, MovementVector.Y);
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(ForwardDirection, MovementVector.X);
AddMovementInput(RightDirection, MovementVector.Y);
}
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UInputAction> mDashAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
float mDashSpeed;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
float mDashDuration;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
float mDashCoolTime;
FVector mDashDirection;
// 대시할 수 있는 상태인지 확인하는 플래그
uint8 mbCanDash : 1;
// 대시를 하는 중인지 확인하는 플래그
uint8 mbIsDashing : 1;
FTimerHandle mDashTimer;
FTimerHandle mDashCoolTimer;
void Dash();
void StartDash();
void EndDash();
void ResetDash();
void AFQPlayerBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent);
EnhancedInputComponent->BindAction(mMoveAction, ETriggerEvent::Triggered, this, &AFQPlayerBase::Move);
EnhancedInputComponent->BindAction(mDashAction, ETriggerEvent::Started, this, &AFQPlayerBase::Dash);
}
void AFQPlayerBase::Dash()
{
mbCanDash = true;
if (mbCanDash)
{
StartDash();
}
}
void AFQPlayerBase::StartDash()
{
if (!mbIsDashing)
{
mbCanDash = false;
mbIsDashing = true;
mDashDirection = GetLastMovementInputVector().GetSafeNormal();
if (mDashDirection.IsZero())
{
mDashDirection = GetActorForwardVector();
}
GetCharacterMovement()->MaxWalkSpeed = mDashSpeed;
GetCharacterMovement()->MaxAcceleration = mDashSpeed * 2;
GetWorld()->GetTimerManager().SetTimer(mDashTimer, this, &AFQPlayerBase::EndDash, mDashDuration, false);
GetWorld()->GetTimerManager().SetTimer(mDashCoolTimer, this, &AFQPlayerBase::ResetDash, mDashCoolTime, false);
}
}
void AFQPlayerBase::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
if (mbIsDashing)
{
AddMovementInput(mDashDirection, mDashSpeed * DeltaSeconds);
}
}
void AFQPlayerBase::EndDash()
{
mbIsDashing = false;
GetCharacterMovement()->MaxWalkSpeed = 200.0f;
GetCharacterMovement()->MaxAcceleration = 2048.0f;
}
void AFQPlayerBase::ResetDash()
{
mbCanDash = true;
}
void AFQPlayerBase::Move(const FInputActionValue& Value)
{
if (mbIsDashing)
{
return;
}
FVector2D MovementVector = Value.Get<FVector2D>();
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(ForwardDirection, MovementVector.X);
AddMovementInput(RightDirection, MovementVector.Y);
}
Dash 안에 StartDash 함수를 굳이 만든 이유?
추후 멀티플레이 환경으로 로직을 수정하기 위해서이다.
: 위치를 변경했을 때 서버와 클라이언트가 동기화되기 위해서는 서버에서 해당 로직을 수행해야 하기 때문에 대시 가능 상태인지 확인하는 플래그가 필요하다고 생각했다.
