증상

  • 차량이 도로 끝까지 잘 갔는데 멈추지 않고 도로 끝에 있는 건물에 그대로 박음
  • 도로 끝에서 정지 기능을 추가해야 함


1차 변경

void HandlePathCompleted()
{
    Pawn->DoThrottle(0.f);    // 가속 페달 떼기
    Pawn->DoBrakeStart();     // 후미등 켜기
    SetComponentTickEnabled(false);
}

 

가속 페달 떼고 후미등 켜면 멈출 줄 알았음

근데 여전히 건물에 박음

차량 폰 코드를 확인해봄

void ATeam24VehiclePawn::DoBrakeStart()
{
    BrakeLights(true);  // 후미등(브레이크등)만 켬
}

 

DoBrakeStart는 후미등만 켜는 함수였음

함수 이름을 헷갈림..

 


2차 변경

void HandlePathCompleted()
{
    Pawn->DoThrottle(0.f);
    Pawn->DoBrake(1.f);       // 실제 브레이크 100%
    Pawn->DoSteering(0.f);
    Pawn->DoBrakeStart();     // 후미등
    SetComponentTickEnabled(false);
}

 

DoBrake(1.f) 추가하면 진짜 브레이크가 걸림

근데 여전히 건물 충돌

시속 60km로 주행 중
   ↓ 도로 끝 1m 전 도달
   ↓ HandlePathCompleted 호출
   ↓ DoBrake(1.f) 시작
   ↓ 브레이크 거리: 5~10m
   ↓ 도로 끝에서 5~10m 지나친 위치에서 정지

 

 

자동차의 관성을 고려하면 미리 감속을 해야함


3차 변경 - 미리 감속 로직 추가

 

UpdateTargetSpeed에 도로 끝 감속 로직 추가

float UpdateTargetSpeed(...)
{
    // ... 기존 곡률 기반 속도 계산 ...
    
    // 도로 끝 미리 감속
    if (Spline && !Spline->IsClosedLoop())
    {
        const float Remaining = Spline->GetSplineLength() - CurrentDistance;
        
        if (Remaining < EndApproachDistance)
        {
            const float Ratio = FMath::Clamp(Remaining / EndApproachDistance, 0.f, 1.f);
            const float EndSpeedLimit = FMath::Lerp(MinSpeed, MaxSpeed, Ratio);
            SpeedLimit = FMath::Min(SpeedLimit, EndSpeedLimit);
        }
    }
}

 

도로 끝에 가까워지면 점진적으로 MaxSpeed에서 MinSpeed로 감속하도록 함

여전히 건물 충돌

감속이 너무 약함

 


4차 변경 - 차량 블루프린트 값 조정

 

코드를 더 건드리기 전에 디테일 패널에서 값부터 조정해봄

차량 블루프린트 → SplineFollowerComponent 디테일 패널

Autopilot|Speed
├── Max Speed: 1500
├── Min Speed: 100         ← 100으로 줄임
└── Decel Rate: 0.5 → 2.0  ← 4배 크게

Autopilot|Path
├── End Of Path Threshold: 100 → 1000  ← 10m 미리 정지
├── Max Road Deviation: 1500
└── End Approach Distance: 2000 → 5000 ← 50m 미리 감속
  • 차량이 거의 정지 상태로 도로 끝에 도달
  • 건물 충돌 없음

근데 새로운 문제 발생 ㅜㅜ 

차량이 멈춘 후 거꾸로 도로를 따라 후진하기 시작함...

 


5차 변경

const float EndSpeedLimit = FMath::Lerp(MinSpeed, MaxSpeed, Ratio);
//                                       ↑
//                                  MinSpeed = 400 (4m/s)

 

로그 찍어보니까 도로 끝에 가까워져도 속도가 MinSpeed(400) 이하로는 안 내려감

차량이 정지 후 다시 MinSpeed를 향해 가속 시도하는 게 아닐까 해서 코드 수정

// 변경 전: MinSpeed(400)까지만 감속
const float EndSpeedLimit = FMath::Lerp(MinSpeed, MaxSpeed, Ratio);

// 변경 후: 0까지 감속
const float EndSpeedLimit = MaxSpeed * Ratio;

 

ApplySpeedCommand에 안전장치도 추가

if (TargetSpeed < 50.f)
{
    Pawn->DoBrake(1.f);  // 거의 정지 시 강제 브레이크
    return;
}

 

여전히 후진....

 


6차 변경 - 디버그 로그 추가

매 프레임 상태를 출력해봄

UE_LOG(LogTemp, Warning, 
    TEXT("Tick: completed=%d, dist=%.1f, speed=%.0f"),
    bPathCompleted ? 1 : 0, 
    CurrentDistance, 
    OwnerPawn->GetVelocity().Size());

 

 

로그 결과

  • bPathCompleted=1: 정지 상태로 진입함
  • CurrentDist 고정: 위치는 안 변함
  • VehicleSpeed가 계속 증가: 2685 → 2686 → 2687

브레이크 걸고 있는데 속도가 오히려 늘어남

???????

 

ai에게 물어봐서 원인을 찾았음

언리얼 5의 Chaos Vehicle은 자체 상태 머신을 가지고 있음

차량이 정지 상태에서 브레이크를 계속 입력하면

"브레이크 입력 100%? 알겠어"
"근데 차가 거의 정지 상태네"
"브레이크 더 누르면 후진 의도네"
"자동 후진 기어로 전환"

 

차량 폰의 DoBrake

void ATeam24VehiclePawn::DoBrake(float BrakeValue)
{
    ChaosVehicleMovement->SetBrakeInput(BrakeValue);
    ChaosVehicleMovement->SetThrottleInput(0.0f);
}

 

이건 그냥 브레이크 입력만 거는데 Chaos 내부 로직이 정지 상태 + 브레이크 = 후진으로 해석한 것

 


7차 변경 - 물리 속도 강제 0

if (USkeletalMeshComponent* Mesh = Pawn->GetMesh())
{
    Mesh->SetPhysicsLinearVelocity(FVector::ZeroVector);
    Mesh->SetPhysicsAngularVelocityInDegrees(FVector::ZeroVector);
}

 

매 프레임 속도를 0으로 강제 설정

차량 폰의 DoResetVehicle이 쓰는 기법을 차용해봄

여전히 후진

속도를 한순간 0으로 만들어도 다음 프레임에 Chaos가 다시 후진 시도

 


8차 변경 

이제 진짜 모르겠어서 근본적으로 접근을 바꿈

물리 입력으로 제어하는 게 한계라면 물리 시뮬레이션 자체를 꺼버림

void HandlePathCompleted()
{
    ATeam24VehiclePawn* Pawn = OwnerPawn.Get();
    if (!Pawn) return;

    Pawn->DoBrakeStart();  // 후미등 (시각 효과)
    
    // 핵심: 물리 시뮬레이션 완전 중지
    if (USkeletalMeshComponent* Mesh = Pawn->GetMesh())
    {
        Mesh->SetSimulatePhysics(false);
    }

    UE_LOG(LogTeam24, Log, TEXT("Path completed - vehicle stopping."));
    bPathCompleted = true;
    SetComponentTickEnabled(false);
}

 

SetSimulatePhysics(false) 호출 시

  • Chaos Vehicle의 모든 물리 처리 중단
  • 차량이 박제됨 (현재 위치에 완전 고정)
  • 후진, 굴러감, 미세 움직임 모두 사라짐
  • 그래픽은 그대로 표시 (시각적으로 자연스러움)
[정상 주행]
↓ 도로 끝 도달
↓ HandlePathCompleted 호출
↓ SetSimulatePhysics(false)
↓ 차량 완전 정지

팀원분이 오류 수정해주심

 

팀원분이 제공한 트러블 슈팅

변경
  • 대상: Pawn에 있는 ChaosVehicleMovement 컴포넌트
  • 설정 변경: bReverseAsBrake 값을 false로 변경
상세 내용 
Pawn의 ChaosVehicleMovement 컴포넌트의 CalcThrottleBrakeInput 함수에는 브레이크 입력을 어떻게 처리할지 결정하는 bReverseAsBrake라는 bool 변수가 있습니다.
  이 값에 따라 차량의 제동 방식이 크게 달라집니다.
  • true (아케이드/게임 모드): 브레이크 키를 계속 누르고 있으면 차량이 정지한 후 자동으로 후진하게 됩니다.
  • false (시뮬레이터/수동 모드) [적용 사항]: 브레이크는 오직 제동(감속 및 정지) 역할만 수행합니다.

-> 8차 변경을 취소하고 다시 브레이크 사용하여 멈추는 걸로 작동하게 함.

void HandlePathCompleted()
{
    Pawn->DoThrottle(0.f);
    Pawn->DoBrake(1.f);       // 실제 브레이크 100%
    Pawn->DoSteering(0.f);
    Pawn->DoBrakeStart();     // 후미등
    SetComponentTickEnabled(false);
}

알게된 것

1. 차량을 멈추는 것은 단순하지 않음

[Naive 접근]
"브레이크 밟으면 멈추겠지" → 실패

[Intermediate]
"미리 감속하고 핸드브레이크 추가" → 실패

[Advanced]
"물리 입력 + 속도 강제 0" → 실패

[Correct]
"물리 시뮬레이션 자체를 끄자" → 성공

 

언리얼의 Chaos Vehicle 시스템은 자체 상태 머신을 가지고 있어서 단순한 입력 명령으로는 완전 제어 불가

 

2. 함수 이름만 믿지 말 것

DoBrakeStart()  // 이름만 보면 "브레이크 시작"
                // 실제: 후미등만 켬

 

함수 이름이 직관적이지 않을 때가 많음

실제 구현을 봐야 정확한 동작을 알 수 있음

 

3. 추측보다 디버그 로그

Tick: completed=1, dist=310658.2, speed=2685
Tick: completed=1, dist=310658.2, speed=2686
Tick: completed=1, dist=310658.2, speed=2687

 

이 로그를 보고서야 정지 상태에서 속도가 증가한다는 건 차량이 능동적으로 움직이는 거구나를 깨달음

추측만 했다면 영원히 핸드브레이크 강도만 조정했을 것

 

4. 시행착오의 잔재를 정리하자

해결 과정에서 추가한 코드들이 많이 쌓였음

// 후진 방지 시도 1
Pawn->DoBrake(1.f);

// 후진 방지 시도 2
Pawn->DoHandbrakeStart();

// 후진 방지 시도 3
Mesh->SetPhysicsLinearVelocity(FVector::ZeroVector);

// 진짜 해결
Mesh->SetSimulatePhysics(false);

 

마지막 해결책 찾고 나서 보면 앞의 시도들은 다 불필요함

SetSimulatePhysics(false) 하면 차량 완전 박제니까 입력 명령이나 속도 제어가 의미 없음

 

5. 게임 엔진의 시스템 이해

일반적인 추론:
"브레이크 = 정지" 

게임 엔진의 현실:
"브레이크 입력 → Chaos 상태 머신 → 기어 판단 → 후진/전진/중립 결정"

 

특정 엔진/시스템을 다룰 때는 그 시스템의 동작 모델을 이해해야 함

일반적인 직관이 안 통할 수 있음

 

+ Recent posts