#pragma once #include "CoreMinimal.h" #include "GameFramework/Character.h" #include "TPSPlayer.generated.h" UCLASS() class MYTPS_API ATPSPlayer : public ACharacter { GENERATED_BODY() public: // Sets default values for this character's properties ATPSPlayer(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; UPROPERTY(EditAnywhere) class USpringArmComponent* springArmComp; UPROPERTY(EditAnywhere) class UCameraComponent* cameraComp; void OnInputHorizontal(float value); void OnInputVertical(float value); void OnInputMouseX(float value); void OnInputMouseY(float value); void OnInputJump(); FVector direction; float speed = 600.f; };
#include "TPSPlayer.h" #include "GameFramework/SpringArmComponent.h" #include "Camera/CameraComponent.h" #include "GameFramework/CharacterMovementComponent.h" // Sets default values ATPSPlayer::ATPSPlayer() { // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; // 에셋 찾아오기 ConstructorHelpers::FObjectFinder<USkeletalMesh> tempBody(TEXT("SkeletalMesh'/Game/Characters/Mannequins/Meshes/SKM_Quinn.SKM_Quinn'")); // 스켈레탈 메쉬 적용 if (tempBody.Succeeded()) // nullptr이면 실행 안함 { GetMesh()->SetSkeletalMesh(tempBody.Object); GetMesh()->SetRelativeLocationAndRotation(FVector(0, 0, -90), FRotator(0, -90, 0)); } // 스프링암, 카메라 배치 springArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("springArmComp")); springArmComp->SetupAttachment(RootComponent); springArmComp->SetRelativeLocation(FVector(0, 50, 60)); springArmComp->TargetArmLength = 120.f; cameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("cameraComp")); cameraComp->SetupAttachment(springArmComp); // 카메라 회전 설정 bUseControllerRotationYaw = true; springArmComp->bUsePawnControlRotation = true; GetCharacterMovement()->bOrientRotationToMovement = false; } // Called when the game starts or when spawned void ATPSPlayer::BeginPlay() { Super::BeginPlay(); } // Called every frame void ATPSPlayer::Tick(float DeltaTime) { Super::Tick(DeltaTime); // 플레이어 이동 direction = FTransform(GetControlRotation()).TransformVector(FVector::ZeroVector); // 컨트롤러 Rotation을 로컬에서 월드로 Vector Transform AddMovementInput(direction); // 컨트롤러 기준으로 벡터 계산 } // Called to bind functionality to input void ATPSPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerInputComponent); // 축 입력 바인딩 PlayerInputComponent->BindAxis(TEXT("Move Right / Left"), this, &ATPSPlayer::OnInputHorizontal); PlayerInputComponent->BindAxis(TEXT("Move Forward / Backward"), this, &ATPSPlayer::OnInputVertical); PlayerInputComponent->BindAxis(TEXT("Turn Right / Left Mouse"), this, &ATPSPlayer::OnInputMouseX); PlayerInputComponent->BindAxis(TEXT("Look Up / Down Mouse"), this, &ATPSPlayer::OnInputMouseY); // 액션 입력 바인딩 PlayerInputComponent->BindAction(TEXT("Jump"), IE_Pressed, this, &ATPSPlayer::OnInputJump); } void ATPSPlayer::OnInputHorizontal(float value) { direction.Y = value; // 좌우 이동 } void ATPSPlayer::OnInputVertical(float value) { direction.X = value; // 전후 이동 } void ATPSPlayer::OnInputMouseX(float value) { AddControllerYawInput(value); } void ATPSPlayer::OnInputMouseY(float value) { AddControllerPitchInput(value); } void ATPSPlayer::OnInputJump() { ACharacter::Jump(); }
AController : 컨트롤러 클래스에 입력값을 저장해놓고, 필요한 곳(Character Movement Component)에서 꺼내 사용하는 구조
(TPS 게임 기준) 항상 카메라가 캐릭터의 정면 방향을 바라보게 한다.