[CH4-11] 캐릭터 걷기, 슬라이드 속도 조절 & 슬라이드 토글 만들기

김여울·2025년 9월 24일
0

내일배움캠프

목록 보기
83/111

기존에 블루프린트에서 속도가 설정되어 있어서
슬라이드 시작하면 느리고 슬라이드 끝나고 걸으면 너무너무 느림...

해야할 것

1️⃣ 걷기 속도 고정하기 : 400

2️⃣ 슬라이드 조건 설정하기

  • Shift 누르기 (슬라이드 시작)
    CharacterMovement → MaxWalkSpeed = SlideSpeed
  • WASD로 방향 바꾸기
  • Shift 눌러서 일어나기 (슬라이드 끝)
    CharacterMovement → MaxWalkSpeed = WalkSpeed
  • 걸을 때 속도 다시 원상태로 400
    → 토글 형식으로 바꾸기

3️⃣슬라이드 속도 설정하기 : 300

기존 코드

DCCharacter.h

UCLASS()
class DC_API ADCCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    /** 외부에서 속도 설정 */
    void SetCharacterSpeed(float NewSpeed);

protected:
    UPROPERTY(ReplicatedUsing=OnRep_IsSliding)
    bool bIsSliding = false;

    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Movement")
    float WalkSpeed = 400.f;

    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Movement")
    float MaxSpeed = 600.f;
};

DCCharacter.cpp

void ADCCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    if (UEnhancedInputComponent* EIC = Cast<UEnhancedInputComponent>(PlayerInputComponent))
    {
        EIC->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::Jump);
        EIC->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
        EIC->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ADCCharacter::Move);
        EIC->BindAction(LookAction, ETriggerEvent::Triggered, this, &ADCCharacter::Look);
        EIC->BindAction(DanceAction, ETriggerEvent::Started, this, &ADCCharacter::Dance);
        EIC->BindAction(AttackAction, ETriggerEvent::Started, this, &ADCCharacter::Attack);

        if (SuicideAction)
        {
            EIC->BindAction(SuicideAction, ETriggerEvent::Started, this, &ADCCharacter::Suicide);
        }

        EIC->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ADCCharacter::SpectatorMove);
        EIC->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ADCCharacter::SpectatorAscend);
    }
}

void ADCCharacter::Move(const FInputActionValue& Value)
{
    if (bIsDead || bIsDancing) return;

    const FVector2D Axis = Value.Get<FVector2D>();
    if (Controller)
    {
        const FRotator ControlRot = Controller->GetControlRotation();
        const FVector Forward = FRotationMatrix(ControlRot).GetUnitAxis(EAxis::X);
        const FVector Right = FRotationMatrix(ControlRot).GetUnitAxis(EAxis::Y);

        AddMovementInput(Forward, Axis.Y);
        AddMovementInput(Right, Axis.X);
    }
}

void ADCCharacter::Look(const FInputActionValue& Value)
{
    const FVector2D Axis = Value.Get<FVector2D>();
    if (Controller)
    {
        AddControllerYawInput(Axis.X);
        AddControllerPitchInput(Axis.Y);
    }
}

void ADCCharacter::StartSlide(const FInputActionValue&)
{
    if (!bIsSliding)
    {
        UE_LOG(LogTemp, Warning, TEXT("슬라이드 시작"));
        Server_SetIsSliding(true);
        Server_ApplySlidePush();
    }
    else
    {
        UE_LOG(LogTemp, Warning, TEXT("슬라이드 종료"));
        Server_SetIsSliding(false);
    }
}

void ADCCharacter::SetCharacterSpeed(float NewSpeed)
{
    float ClampedSpeed = FMath::Clamp(NewSpeed, WalkSpeed, MaxSpeed);
    if (GetCharacterMovement())
    {
        GetCharacterMovement()->MaxWalkSpeed = ClampedSpeed;
        UE_LOG(LogTemp, Warning, TEXT("이동 속도가 %f 로 설정되었습니다."), ClampedSpeed);
    }
}

void ADCCharacter::OnRep_IsSliding()
{
    if (bIsSliding)
    {
        GetCharacterMovement()->MaxWalkSpeed = 300.f;
    }
    else
    {
        GetCharacterMovement()->MaxWalkSpeed = WalkSpeed;
    }
}

수정 코드

DCCharacter.h

// 걷기/슬라이드 속도
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Movement")
float WalkSpeed = 400.f;

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Movement")
float SlideSpeed = 300.f;

// 슬라이드 토글
void ToggleSlide(const struct FInputActionValue& Value);

DCCharacter.cpp

1️⃣ OnRep_IsSliding 수정

void ADCCharacter::OnRep_IsSliding()
{
    if (!GetCharacterMovement()) return;

    if (bIsSliding)
    {
        // 엎드렸을 때
        GetCharacterMovement()->MaxWalkSpeed = SlideSpeed;
        GetCharacterMovement()->SetMovementMode(MOVE_Walking); // 기어가도 Walking 유지
    }
    else
    {
        // 다시 걷기
        GetCharacterMovement()->MaxWalkSpeed = WalkSpeed;
        GetCharacterMovement()->SetMovementMode(MOVE_Walking);
    }
}

2️⃣ ToggleSlide 함수

void ADCCharacter::ToggleSlide(const FInputActionValue& /*Value*/)
{
    if (!bIsSliding)
    {
        // 엎드리기 시작
        bIsSliding = true;
        Server_SetIsSliding(true);

        UE_LOG(LogTemp, Warning, TEXT("엎드리기 시작"));
    }
    else
    {
        // 일어나기
        bIsSliding = false;
        Server_SetIsSliding(false);

        UE_LOG(LogTemp, Warning, TEXT("일어나기"));
    }
}

3️⃣ 입력 바인딩 (SetupPlayerInputComponent)

if (SlideAction)
{
    // Shift 한 번 누르면 엎드리기/일어나기 토글
    EIC->BindAction(SlideAction, ETriggerEvent::Started, this, &ADCCharacter::ToggleSlide);
}

  • Shift 누르면 → 엎드리기 (속도 300)
  • Shift 또 누르면 → 일어나기 (속도 400)
  • 엎드린 동안은 WASD 이동 가능, Shift 안 누르고도 계속 유지됨!

0개의 댓글