대각선 맵
스택오버플로우 해결

좀보이드는 맵이 대각선으로 기울어진 형태로 되어 있다. 건물, 차, 방의 구조 등 모두 대각선 형태
하지만, 맵에서 액터를 배치할 때 항상 대각선으로 돌려서 배치하기엔 너무 효율성이 떨어질 것 같아 다른 방법이 없을까 고민해보았다
그래서 맵을 대각선으로 돌리는 대신에 카메라를 45도 회전시키면 동일한 효과를 나타낼 수 있을 것 같아 레벨에 액터는 똑바르게 배치하고, 카메라만 회전시켜 해결하였다
// PlayerCharacter.cpp
SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
SpringArm->SetupAttachment(RootComponent);
SpringArm->SetUsingAbsoluteRotation(true);
SpringArm->TargetArmLength = 1800.f;
SpringArm->SetRelativeRotation(FRotator(-50.f, 45.f, 0.f));
SpringArm->bDoCollisionTest = false;
탑다운 방식이므로 스프링암을 위로 회전시키고, 대각방향으로 회전시켜주었다
탑다운 방식의 게임에선 카메라가 벽에 부딪힌다고 스프링암의 길이가 줄어들거나 하면 안 되므로, bDoCollisionTest를 false로 설정하여, 카메라가 고정된 느낌을 주도록 하였다
// PlayerCharacter.cpp
void AMyCharacter::MoveAction(const FInputActionValue& Value)
{
const FVector2D InMovementVector = Value.Get<FVector2D>();
AddMovementInput(Camera->GetForwardVector(), InMovementVector.X);
AddMovementInput(Camera->GetRightVector(), InMovementVector.Y);
}
카메라가 회전되었기에 월드가 회전된 것처럼 보이지만, 캐릭터의 이동은 카메라가 바라보는 기준으로 상하좌우로 움직여야 함
따라서, 월드나 컨트롤러를 기준으로 하는 것이 아닌 카메라를 기준으로 삼아 이동
ACharacter가 기본적으로 가지고 있는 Crouch함수를 사용하려고 함
bIsCrouched 변수를 통해, 현재 캐릭터가 앉아있는지, 아닌지를 확인
GetCharacterMovement()->NavAgentProps.bCanCrouch 값을 참으로 해줘야 실제로 앉기가 작동함
원하는 속도로 움직이게 하고 싶어 MaxWalkSpeedCrouched에 직접 값 입력
Crouch함수가 호출되면 캡슐 사이즈도 작아지면서 스프링암도 밑으로 당겨지게 된다. 그래서 SpringArm->bEnableCameraLag을 참으로 하여 카메라가 부드럽게 이동하게 함
이러면 위치, 회전만 부드럽게 되는거고 타겟암의 길이변화에 대해선 해당되지 않음
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
EnhancedInput->BindAction(PlayerController->CrouchAction,
ETriggerEvent::Started,
this,
&AMyCharacter::StartCrouch);
}
void AMyCharacter::StartCrouch(const FInputActionValue& Value)
{
if (GetCharacterMovement())
{
if (bIsCrouched)
{
GetCharacterMovement()->MaxWalkSpeedCrouched = BaseWalkSpeed;
UnCrouch(true);
}
else
{
if (CanCrouch())
{
GetCharacterMovement()->MaxWalkSpeedCrouched =
BaseWalkSpeed * CrouchSpeedMultiplier;
Crouch(true);
}
}
}
}
지역변수를 너무 많이 할당받거나, 재귀함수를 계속 호출하여 스택의 용량이 부족할 때 발생
해결법으로는 아래와 같음
크기가 너무 큰 지역변수는 new를 이용해 힙에 할당받음
재귀함수의 최대 깊이 한도를 조절하여 설계함 (memoization으로도 가능)
재귀함수를 사용하지 않고 반복문을 이용해 stack메모리를 계속 할당받지 않도록 함
애초에 컴파일 전에 스택메모리 크기 제한을 풀어 좀 많이 늘려버린다
reserve
commit