오늘의 목표

  • 아침 코드카타
  • 과제 7번 필수기능 구현 
  • 과제 7번 도전기능 구현

아침 코드카타

 

[문제] 3진법 뒤집기

 

 

 

int solution(int n) {

    int trinary = 0;
    int answer = 0;

    while (n >= 1)
    {
        trinary = trinary * 10 + n % 3;
        n /= 3;
    }

    int multiplier = 1;
    for (int i = 0; trinary>= 1; ++i)
    {
        answer = answer + multiplier * (trinary % 10);
        trinary /= 10;
        multiplier *= 3;
    }

    return answer;
}

 

 

 

    int* trinary = (int*) malloc(sizeof(int) * 10);

 

기억해둘 개념

malloc은 void* 값을 반환하므로 반드시 원하는 포인터 자료형으로 변환시켜줘야한다.

 

[더 나은 풀이법]

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int solution(int n) {
    int answer = 0;

    while(n >= 1)
    {
        answer = (answer * 3) + (n % 3);
        n /= 3;
    }

    return answer;
}

 

기존에 내가 사용했던 풀이법은 10진법을 기준으로 계산하느라 * 10, / 10 연산을 했는데, 그 연산을 제외하고 3진수 형식으로 3을 곱한 뒤 각 자릿수를 더하는 방식으로 10진수로의 변환도 한 번에 할 수 있다고 한다.

 

answer = answer * 3 + 나머지

이 수식이 3진수를 10진수로 변환할 때 사용하는 수학 공식을 그대로 계산하는 것과 같다.

 


 

7번 과제 필수 기능 구현

액션 바인딩

 

BeginPlay()

void AMyPawn::BeginPlay()
{
	Super::BeginPlay();
    
	if (APlayerController* PC = Cast<APlayerController>(Controller))
	{
		if (UEnhancedInputLocalPlayerSubsystem * Subsystem =
			ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
		{
			Subsystem->AddMappingContext(DefaultMappingContext, 0);
		}
	}
}

 

1. 컨트롤러 캐스팅

	if (APlayerController* PC = Cast<APlayerController>(Controller))

 

 

   

 Controller

-Pawn 기본 변수, 이 Pawn을 조종하는 컨트롤러를 가리킴
-APlayerController(플레이어) 혹은 AAIController(AI)일 수 있음

-cast<APlayerController>로 플레이어가 조종중인지 확인

-AI가 조종중이라면 Cast가 nullptr를 반환, if문 스킵

**여기서 선언, 정의 및 존재여부 확인을 동시에 하는 것 같은데?

 

 

3. LocalPlayer -> Subsystem 가져오기

if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
	ULocalPlayer::GetSubsystem<UEnhancedInputPlayerSubsystem>(PC->GetLocalPlayer()))

PC -> GetLocalPlayer()

- APlayerController에서 실제 로컬 플레이어 객체(ULocalPlayer)를 가져옴

- 멀티에서는 원격 플레이어도 존재하므로 로컬 플레이어만 입력 처리

 

ULocalPlayer::GetSubsystem<>()

- UE5의 Subsystem 시스템을 사용해 Enhanced Input 서브시스템을 가져옴

- Subsystem은 UE5에서 특정 기능을 담당하는 싱글턴 매니저 역할

- Enhanced Input 관련 기능은 모두 이 Subsystem을 통해 처리

 

3. Mapping Context 등록

Subsystem->AddMappingContext(DefaultmappingContext, -0);

DefaultMappingContext : 등록할 UInputMappingContext 에셋 (블루프린트에서 편집 가능하도록 설정함)

0 : 우선순위.

 

BeginPlay에서 Mapping Context 등록해야하는 이유: 컨트롤러는 게임 시작 후 possess 완료된 뒤에 유효하기 때문에 반드시 BeginPlay 이후에 접근해야 함.

 

이동 및 회전 로직 구현

 

 

헤더 파일

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "InputActionValue.h"
#include "MyPawn.generated.h"

class UCapsuleComponent;
class USkeletalMeshComponent;
class USpringArmComponent;
class UCameraComponent;

UCLASS()
class ASSIGNMENT7_API AMyPawn : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	AMyPawn();

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;


protected:

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "CapsuleComponent")
	UCapsuleComponent* CapsuleComp;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SkeletalMesh")
	USkeletalMeshComponent* SkeletalMeshComp;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SpringArm")
	USpringArmComponent* SpringArmComp;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera")
	UCameraComponent* CameraComp;

	UPROPERTY(EditAnywhere, Category = "Input")
	class UInputMappingContext* DefaultMappingContext;
	UPROPERTY(EditAnywhere, Category = "Input")
	class UInputAction* MoveAction;
	UPROPERTY(EditAnywhere, Category = "Input")
	class UInputAction* LookAction;

	void Move(const FInputActionValue& Value);
	void Look(const FInputActionValue& Value);

	FVector2D CurrentInputVector;

	UPROPERTY(EditAnywhere, Category = "Movement")
	float MoveSpeed = 500.0f;
};

 

cpp 파일

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyPawn.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "Components/CapsuleComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"


// Sets default values
AMyPawn::AMyPawn()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("CapsuleComponent"));
	RootComponent = CapsuleComp;
	SkeletalMeshComp = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("SkeletalMeshComponent"));
	SkeletalMeshComp->SetupAttachment(CapsuleComp);
	SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComponent"));
	SpringArmComp->SetupAttachment(CapsuleComp);
	SpringArmComp->TargetArmLength = 300.0f;
	SpringArmComp->bUsePawnControlRotation = true;
	CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
	CameraComp->SetupAttachment(SpringArmComp, USpringArmComponent::SocketName);
	CameraComp->bUsePawnControlRotation = false;

	if (CapsuleComp)
	{
		CapsuleComp->SetSimulatePhysics(false);
	}

	if (SkeletalMeshComp)
	{
		SkeletalMeshComp->SetSimulatePhysics(false);
	}
	
	
}

// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
	Super::BeginPlay();
	if (APlayerController* PC = Cast<APlayerController>(Controller))
	{
		if (UEnhancedInputLocalPlayerSubsystem * Subsystem =
			ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
		{
			Subsystem->AddMappingContext(DefaultMappingContext, 0);
		}
	}
}

// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (!CurrentInputVector.IsNearlyZero())
	{
		const FRotator ControlRotation = GetControlRotation();
		const FRotator YawRotation(0, ControlRotation.Yaw, 0);

		FVector Forward = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
		FVector Right = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);

		FVector Movement = (Forward * CurrentInputVector.Y + Right * CurrentInputVector.X) * MoveSpeed * DeltaTime;
		
		FHitResult Hit;
		AddActorWorldOffset(Movement, true, &Hit);

		CurrentInputVector = FVector2D::ZeroVector;
		
	}	
}

// Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
	{
		EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyPawn::Move);
		EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMyPawn::Look);
	}
}

void AMyPawn::Move(const FInputActionValue& Value)
{
	// 입력값 2D벡터로 가져옴
	CurrentInputVector = Value.Get<FVector2D>();
}

void AMyPawn::Look(const FInputActionValue& Value)
{
	FVector2D LookInput = Value.Get<FVector2d>();
	if (Controller)
	{
		AddControllerYawInput(LookInput.X);
		AddControllerYawInput(LookInput.Y);

	}
}

 

 

LookInput = Value.Get<FVector2D>();

     

 

 

'Unreal5 공부 > TIL' 카테고리의 다른 글

2026/04/22  (0) 2026.04.22
2026/4/21 TIL  (0) 2026.04.21
2026/04/17 TIL  (2) 2026.04.17
2026/04/16 TIL  (0) 2026.04.16
2026/04/15 TIL  (1) 2026.04.15

+ Recent posts