🔍 문제 상황
Pawn 클래스를 만들고 Enhanced Input을 사용하여 이동을 구현했음.
하지만 마우스 입력이 작동하지 않음 → 카메라 회전이 불가능함.
🛠 원인 분석 & 해결 방법
PlayerController의 마우스 입력이 비활성화되어 있을 가능성이 높음.
해결 방법: APlayerController::bShowMouseCursor와 APlayerController::bEnableClickEvents 등을 설정하여 마우스 입력 활성화.
✅ 해결 코드:
void ASpartaPawn::BeginPlay()
{
Super::BeginPlay();
APlayerController* PC = Cast<APlayerController>(GetController());
if (!PC)
{
PC = GetWorld()->GetFirstPlayerController();
if (PC)
{
PC->Possess(this);
}
}
// ✅ 마우스 입력 활성화
if (PC)
{
PC->bShowMouseCursor = false;
PC->bEnableClickEvents = false;
PC->bEnableMouseOverEvents = false;
PC->SetInputMode(FInputModeGameOnly()); // 🔥 게임 전용 입력 모드로 변경
}
// ✅ Enhanced Input Mapping 적용
if (PC)
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
{
if (IMC_Pawn)
{
Subsystem->AddMappingContext(IMC_Pawn, 0);
}
}
}
}
🔍 문제 상황
MoveForward() 실행 시, 캐릭터가 조금씩 지면 아래로 내려가는 현상 발생.
Jump() 실행 후에도 땅을 뚫고 떨어지는 경우가 있음.
🛠 원인 분석 & 해결 방법
원인은 크게 3가지:
지면 감지 (CheckForGround())의 LineTrace 범위가 너무 짧아서 정상적인 바닥 감지를 못함.
중력 적용 시 SetActorLocation()을 사용하여 충돌을 무시하고 위치를 강제로 이동함.
점프 로직에서 bIsJumping = false;를 너무 빨리 설정하여 점프가 한 프레임만 적용됨.
✅ 해결 방법
LineTrace 범위를 더 넓게 조정하고, 충돌 채널을 ECC_WorldStatic으로 변경.
SetActorLocation() 대신 AddActorWorldOffset(GravityMove, true); 사용하여 충돌을 감지하면서 이동.
점프 상태(bIsJumping)를 착지할 때까지 유지.
✅ 해결 코드:
void ASpartaPawn::CheckForGround()
{
FVector Start = GetActorLocation();
FVector End = Start - FVector(0, 0, Capsule->GetScaledCapsuleHalfHeight() + 10.0f); // ✅ 10 유닛 추가
FHitResult HitResult;
FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(this);
bIsOnGround = GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_WorldStatic, QueryParams);
if (bIsOnGround)
{
FallSpeed = 0.0f; // ✅ 착지 시 낙하 속도 초기화
}
}
void ASpartaPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
FVector CurrentLocation = GetActorLocation();
CheckForGround();
if (!bIsOnGround)
{
FallSpeed += Gravity * DeltaTime;
}
else if (bIsJumping)
{
FallSpeed = JumpSpeed; // ✅ 착지 시 한 번 더 점프 속도 적용
bIsJumping = false;
}
else
{
FallSpeed = 0.0f;
}
FVector GravityMove = FVector(0.0f, 0.0f, FallSpeed * DeltaTime);
AddActorWorldOffset(GravityMove, true); // ✅ Sweep 활성화로 충돌 감지!
}
🔍 문제 상황
점프 버튼을 눌러도 캐릭터가 거의 점프하지 않거나, 점프 후 땅속으로 사라지는 경우가 있음.
🛠 원인 분석 & 해결 방법
bIsJumping = false;를 너무 빨리 설정해서 점프 속도가 한 프레임만 적용됨.
점프 입력이 들어가면 bIsJumping을 true로 유지하고, 착지 시 false로 변경해야 함.
✅ 해결 코드:
void ASpartaPawn::Jump(const FInputActionValue& Value)
{
if (bIsOnGround && !bIsJumping)
{
bIsJumping = true;
FallSpeed = JumpSpeed; // ✅ 점프 속도 설정
}
}
✅ 1. 마우스 입력이 안될 때는 PlayerController의 입력 설정을 확인하자!
bShowMouseCursor = false;
SetInputMode(FInputModeGameOnly());
bEnableClickEvents = false;
✅ 2. LineTrace를 사용할 때 끝점을 너무 짧게 설정하면 바닥 감지를 못할 수 있다.
LineTrace의 끝점을 Capsule HalfHeight보다 더 아래로 조정해야 함.
ECC_WorldStatic 충돌 채널을 사용해야 더 정확한 감지가 가능함.
✅ 3. 중력 적용 시 SetActorLocation() 대신 AddActorWorldOffset(GravityMove, true);을 사용하자!
SetActorLocation()은 충돌을 무시하고 강제로 이동시키기 때문에 캐릭터가 땅을 뚫을 수 있음.
AddActorWorldOffset(GravityMove, true);를 사용하면 충돌을 감지하면서 자연스럽게 이동 가능.
✅ 4. 점프 로직을 구현할 때는 bIsJumping을 착지할 때까지 유지해야 한다.
점프 버튼을 누르면 bIsJumping = true;
착지할 때만 bIsJumping = false;로 변경해야 한다.