#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "SpartaCharacter.generated.h"
// EnhancedInput에서 액션 값을 받을 때 사용하는 구조체
struct FInputActionValue;
UCLASS()
class SPARTA_API ASpartaCharacter : public ACharacter
{
GENERATED_BODY()
public:
ASpartaCharacter();
protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
class USpringArmComponent* SpringArmComp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
class UCameraComponent* CameraComp;
// Sprint 액션에 사용되는 변수
// 기본 스피드
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
float NormalSpeed;
// 스피드 변화 값
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
float SprintSpeedMultiplier;
// Sprint 상태일 때 스피드
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
float SprintSpeed;
public:
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// 입력이 들어왔을 때 실제로 호출되는 함수
UFUNCTION()
void Move(const FInputActionValue& value);
UFUNCTION()
void StartJump(const FInputActionValue& value);
UFUNCTION()
void StopJump(const FInputActionValue& value);
UFUNCTION()
void Look(const FInputActionValue& value);
UFUNCTION()
void StartSprint(const FInputActionValue& value);
UFUNCTION()
void StopSprint(const FInputActionValue& value);
};
#include "SpartaCharacter.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "SpartaPlayerController.h"
#include "EnhancedInputComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
void ASpartaCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
//Enhanced Input Component 로 캐스팅
if (UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{
// IA를 가져오기 위해 현재 소유중인 Controller를 ASpartaPlayerController로 캐스팅
if (ASpartaPlayerController* PlayerController = Cast<ASpartaPlayerController>(GetController()))
{
// IA_Move(WASD) 입력이 들어왔을 때
if (PlayerController->MoveAction)
{
//키를 누르고 있는동안 Move() 호출
EnhancedInput->BindAction(
PlayerController->MoveAction,
ETriggerEvent::Triggered,
this,
&ASpartaCharacter::Move
);
}
// IA_Jump(Spacebar) 입력이 들어왔을 때
if (PlayerController->JumpAction)
{
// 키를 누르고 있는 동안 StartJump() 호출
EnhancedInput->BindAction(
PlayerController->JumpAction,
ETriggerEvent::Triggered,
this,
&ASpartaCharacter::StartJump
);
// 키를 뗀 순간 StopJump() 호출
EnhancedInput->BindAction(
PlayerController->JumpAction,
ETriggerEvent::Completed,
this,
&ASpartaCharacter::StopJump
);
}
// IA_Look(마우스 이동) 입력이 들어왔을 때
if (PlayerController->LookAction)
{
// 마우스가 움직일 때 Look() 호출
EnhancedInput->BindAction(
PlayerController->LookAction,
ETriggerEvent::Triggered,
this,
&ASpartaCharacter::Look
);
}
// IA_Sprint(Left Shift) 입력이 들어왔을 때
if (PlayerController->SprintAction)
{
// 키를 누르고 있는 동안 StartSprint() 호출
EnhancedInput->BindAction(
PlayerController->SprintAction,
ETriggerEvent::Triggered,
this,
&ASpartaCharacter::StartSprint
);
// 키를 뗀 순간 StopSprint() 호출
EnhancedInput->BindAction(
PlayerController->SprintAction,
ETriggerEvent::Completed,
this,
&ASpartaCharacter::StopSprint
);
}
}
}
}
BindAction()void ASpartaCharacter::Move(const FInputActionValue& value)
{
// 컨트롤러가 있어야 방향 계산이 가능
if (!Controller) return;
// IA_Move는 Axis2D로 입력값을 받기 때문에 value는 (X, Y) 형태
// W → (X, 0), S → (-X, 0), A → (0, Y), D → (0, -Y)
const FVector2D MoveInput = value.Get<FVector2D>();
// X값이 있을 때
if (!FMath::IsNearlyZero(MoveInput.X))
{
// 정면으로 X축 이동
AddMovementInput(GetActorForwardVector(), MoveInput.X);
}
// Y값이 있을 때
if (!FMath::IsNearlyZero(MoveInput.Y))
{
// 우측 방향으로 Y축 이동
AddMovementInput(GetActorRightVector(), MoveInput.Y);
}
}
AddMovementInput()
- 어느 방향을 얼만큼 이동할 지 전달하는 함수
- 첫번째 인자 : 월드좌표 기준 방향
- 두번째 인자 : 이동 스케일(속도)
GetActorForwardVector(), GetActorRightVector()
월드 좌표에서 액터의 X(forward), Y(Right) 방향 벡터를 가져옴 (length 1.0)
FMath::IsNearlyZero()
- 부동 소수점을 쓸때는 '값 == 0'을 표현할 때 이 함수를 쓰는 것이 좋음
- 조금의 오차로 다른 결과가 나오는 것을 방지하기 위해?
void ASpartaCharacter::StartJump(const FInputActionValue& value)
{
// 키가 눌렸을 때
if (value.Get<bool>()) Jump();
}
void ASpartaCharacter::StopJump(const FInputActionValue& value)
{
// 키가 눌리지 않았을 때
if (!value.Get<bool>()) StopJumping();
}
Jump(), StopJumping()void ASpartaCharacter::Look(const FInputActionValue& value)
{
// 마우스의 움직임을 Axis2D로 받음
FVector2D LookInput = value.Get<FVector2D>();
// X는 좌우 회전(Yaw)
AddControllerYawInput(LookInput.X);
// Y는 상하 회전 (Pitch)
AddControllerPitchInput(LookInput.Y);
}
AddControllerYawInput(), AddControllerPitchInput()
카메라의 Yaw, Pitch축의 회전값을 변경
마우스 감도 변경
- 프로젝트 설정에서 변경하기

- IA_Look에서 변경하기

ASpartaCharacter::ASpartaCharacter()
{
PrimaryActorTick.bCanEverTick = true;
// 중략
// 기본 이동 속도
NormalSpeed = 600.0f;
// 빠른 이동 시 곱해질 속도 값
SprintSpeedMultiplier = 1.5f;
// 빠른 이동 시 이동 속도
SprintSpeed = NormalSpeed * SprintSpeedMultiplier;
GetCharacterMovement()->MaxWalkSpeed = NormalSpeed;
}
void ASpartaCharacter::StartSprint(const FInputActionValue& value)
{
// 키가 눌렸을 때 빠른 이동 속도로
if (GetCharacterMovement()) GetCharacterMovement()->MaxWalkSpeed = SprintSpeed;
}
void ASpartaCharacter::StopSprint(const FInputActionValue& value)
{
// 키가 떼졌을 때 기본 이동 속도로
if (GetCharacterMovement()) GetCharacterMovement()->MaxWalkSpeed = NormalSpeed;
}
GetCharacterMovement()