[4일차] 복습 겸 오류 고치기

칼든개구리·2024년 12월 5일
0

[언리얼TO리얼]

목록 보기
8/42

나는 분명 강의마다 빠지는거 없이 잘 적었다고 생각했는데 뭔가 안적고 넘어가고 틀리게 적는 부분이 다소 있었나 보다.

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


#include "PlayerBase.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "EnhancedInputComponent.h"
#include "Weapon.h"
#include "EnhancedInputSubsystems.h"
#include "InputMappingContext.h"

APlayerBase::APlayerBase()
{
	//컴포넌트들의 배치
	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->SetupAttachment(RootComponent);

	FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
	FollowCamera->SetupAttachment(CameraBoom);

}

void APlayerBase::BeginPlay()
{
	Super::BeginPlay(); //상속받는 것이니 super로 처리해줘야함
	APlayerController* PC = Cast<APlayerController>(GetController());
	if (IsValid(PC))
	{
		ULocalPlayer* Player = PC->GetLocalPlayer();
		if (UEnhancedInputLocalPlayerSubsystem* InputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(Player))
		{
			InputSubsystem->AddMappingContext(InputMappingContext, 0);
		}
	}




	WeaponActor = GetWorld()->SpawnActor<AWeapon>(Weapon);
	if (Weapon)
	{
		FAttachmentTransformRules TransformRules(EAttachmentRule::SnapToTarget, true);
		WeaponActor->AttachToComponent(GetMesh(), TransformRules, TEXT("WeaponSocekt"));
		WeaponActor->SetOwner(this);
		WeaponActor->SetInstigator(this);
	}

}

void APlayerBase::Hit(int32 Damage, AActor* Bywho)
{
	Super::Hit(Damage, Bywho);
	if (CurrentHP > 0)
	{
		return;
	}
	Destroy();
}

void APlayerBase::IncreaseKillCount()
{
	Super::IncreaseKillCount();
}

void APlayerBase::Attack()

{
	Super::Attack();
	if (IsValid(WeaponActor))
	{
		WeaponActor->Fire();
	}
}

void APlayerBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent))
	{
		EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &APlayerBase::Move);
		EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &APlayerBase::Look);
		EnhancedInputComponent->BindAction(FireAction, ETriggerEvent::Started, this, &APlayerBase::Fire);
		EnhancedInputComponent->BindAction(ZoomAction, ETriggerEvent::Triggered, this, &APlayerBase::Zoom);
	}
}

void APlayerBase::Move(const FInputActionValue& Value)
{
	FVector2D MovementVector = Value.Get<FVector2D>();

	if (Controller != nullptr)
	{
		AddMovementInput(GetActorForwardVector(), MovementVector.X);
		AddMovementInput(GetActorRightVector(), MovementVector.Y);
	}
}

void APlayerBase::Look(const FInputActionValue& Value)
{
	FVector2D LookAxisVector = Value.Get<FVector2D>();
	if (Controller != nullptr)
	{
		AddControllerYawInput(LookAxisVector.X);
		AddControllerYawInput(-LookAxisVector.Y);

	}
}

void APlayerBase::Fire(const FInputActionValue& Value)
{
	//무기 완성 후 작성
	Attack();
}

void APlayerBase::Zoom(const FInputActionValue& Value)
{
	if (!IsValid(CameraBoom)) //IsValid: 널 포인터인지 삭제될 건지 진짜 존재하는지 체크하는 용도
	{
		return;
	}
	if (Value.Get<bool>())
	{
		CameraBoom->TargetArmLength = 40;
		CameraBoom->SocketOffset = FVector(0, 40, 60);

	}
	else
	{
		CameraBoom->TargetArmLength = 120;
		CameraBoom->SocketOffset = FVector(0, 60, 60);
	}
}

선생님이 바로 주신 코드인데 선언한 변수가 나만 없다니.,. 선생님이 빼먹었다고 해줘요,,
InputMappingContext를 찾을 수 없어서 튜터님께 질문을 하였다. 물론 나도 이게 선언되지 않은거라 오류가 났다는 건 알고있는데 내가 잘못적었나.. 라는 생각만 맴돌았다..
튜터님께서는 TObjectPtr InputMappingContext; 선언방식을 알려주시고 강의 내 못따라가는 부분을 알려주셨다.
내가 젤 강의보면서 이해가 안갔던 부분은 선생님은 이후 바로 캐릭터를 움직일 수 있게 하셨다.
내가 알기론 입력 액션을, 입력 매핑 컨텍스트에서 방향에 대해서 부정의 값인지 이런 것을 설정하고 무슨 키를 눌러야(마우스 입력) 총이 나가던가 할텐데 그런 것 없이 움직이고 총을 쏘셨다.
이건 진짜 왜지? 흐음 코드도 어려워죽겠는데 오류랑 자꾸 싸우면 힘이 든다~,~
이번 하루는 좀 쉬는 타임으로 진도를 조금만 나가고 모르는 함수에 대해서 정리를 해볼까 한다

APlayerController* PC = Cast<APlayerController>(GetController());

이 코드는 언리얼 엔진에서 현재 액터(또는 캐릭터)에 연결된 컨트롤러를 가져오고, 그것이 APlayerController인지 확인하며, 올바른 타입으로 변환(Cast)하려는 의도이다.
GetController()가 반환한 컨트롤러가 APlayerController 타입인지 확인합니다.

  • 성공: APlayerController로 캐스팅되고, 결과가 PC에 저장됩니다.
  • 실패: 캐스팅 실패 시 PC는 nullptr이 됩니다
	ULocalPlayer* Player = PC->GetLocalPlayer();
	if (UEnhancedInputLocalPlayerSubsystem* InputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(Player))
	{
		InputSubsystem->AddMappingContext(InputMappingContext, 0);
	}
  1. ULocalPlayer* Player = PC->GetLocalPlayer();
    PC는 현재 캐릭터의 APlayerController입니다.
    GetLocalPlayer()는 플레이어 컨트롤러에서 ULocalPlayer 객체를 반환합니다.
    ULocalPlayer란?

ULocalPlayer는 로컬 플레이어를 나타내는 클래스입니다.
특히 멀티플레이어 환경에서, 하나의 클라이언트가 여러 로컬 플레이어를 가질 수 있습니다.
이를 통해 플레이어별로 고유한 입력 시스템이나 화면 설정을 제어할 수 있습니다

  1. UEnhancedInputLocalPlayerSubsystem* InputSubsystem = ULocalPlayer::GetSubsystem(Player);
  • a. ULocalPlayer::GetSubsystem()
    이 함수는 Player 객체에서 특정 타입의 서브시스템(T)을 가져오는 작업을 수행합니다.
    T는 서브시스템 클래스로, 이 코드에서는 UEnhancedInputLocalPlayerSubsystem입니다.
  • b. UEnhancedInputLocalPlayerSubsystem란?
    강화된 입력 시스템(Enhanced Input System)의 일부로, 로컬 플레이어의 입력 매핑을 관리하는 서브시스템입니다.
    이 서브시스템을 통해:
    입력 매핑을 동적으로 추가/제거하거나,
    입력 처리와 관련된 다양한 설정을 제어할 수 있습니다.
    결과
    GetSubsystem(Player)는 현재 플레이어에 연결된 UEnhancedInputLocalPlayerSubsystem을 반환합니다.
    반환된 결과는 InputSubsystem 변수에 저장됩니다.
    만약 이 플레이어가 해당 서브시스템을 가지지 않으면, nullptr이 반환됩니다.
profile
메타쏭이

0개의 댓글