도, 라디안
도: 원을 360등분한 것
1 라디안: 원의 반지름 길이와 호의 길이가 같아지는 중심각
프로그래밍에서는 라디안을 주로 많이 사용함
예시: FMath::Acos()는 라디안 값을 반환
사람이 읽기 쉬운 도 단위로 바꾸려면 다음 함수를 사용
float AngleDegrees = FMath::RadiansToDegrees(AngleRadians);
cos와 내적의 관계
정규화된 두 방향 벡터를 내적하면, 그 결과는 두 방향 사이 각도의 cos 값과 연결됨

| 각도 | cos 값 | Dot 의미 |
| 0도 | 1 | 완전히 같은 방향 |
| 90도 | 0 | 서로 옆 방향 |
| 180도 | -1 | 완전히 반대 방향 |
내적
두 벡터가 얼마나 같은 방향을 향하고 있는지 판단하는 계산

| Dot 결과 | 의미 |
| 1 | 두 방향이 완전히 같음 |
| 0 | 두 방향이 서로 90도 |
| -1 | 두 방향이 완전히 반대 |
| 0보다 큼 | 대상이 앞쪽 방향에 있음 |
| 0보다 작음 | 대상이 뒤쪽 방향에 있음 |
예제
Target이 앞에 있는지 뒤에 있는지 내적으로 확인하기
if (TargetActor == nullptr)
{
return;
}
FVector Forward = GetActorForwardVector();
FVector ToTarget = TargetActor->GetActorLocation() - GetActorLocation();
FVector DirectionToTarget = ToTarget.GetSafeNormal();
float Dot = FVector::DotProduct(Forward, DirectionToTarget);
if (Dot > 0.0f)
{
UE_LOG(LogTemp, Log, TEXT("Target is in front"));
}
else if (Dot < 0.0f)
{
UE_LOG(LogTemp, Log, TEXT("Target is behind"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("Target is on the side"));
}
캐릭터의 시야각을 내적으로 확인하기
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "View Test")
AActor* TargetActor;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "View Test")
float ViewAngle = 90.0f;
void ADirectionTestActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (TargetActor == nullptr)
{
return;
}
FVector Forward = GetActorForwardVector();
FVector ToTarget = TargetActor->GetActorLocation() - GetActorLocation();
FVector DirectionToTarget = ToTarget.GetSafeNormal();
float Dot = FVector::DotProduct(Forward, DirectionToTarget);
// Clamp로 시야각을 -1.0 ~ 1.0로 막음
Dot = FMath::Clamp(Dot, -1.0f, 1.0f);
float AngleRadians = FMath::Acos(Dot);
float AngleDegrees = FMath::RadiansToDegrees(AngleRadians);
if (AngleDegrees <= ViewAngle * 0.5f)
{
UE_LOG(LogTemp, Log, TEXT("Target is inside view angle. Angle: %f"), AngleDegrees);
}
else
{
UE_LOG(LogTemp, Log, TEXT("Target is outside view angle. Angle: %f"), AngleDegrees);
}
}
외적
두 벡터에 수직인 방향을 구하는 계산

Normal Vector와 표면 방향 판정


예시 코드
FVector HitNormal = HitResult.ImpactNormal;
// 두 단위 벡터를 내적하여 cos(theta) 값을 구함
float UpDot = FVector::DotProduct(HitNormal, FVector::UpVector);
// 기준 스펙: 걸어 올라갈 수 있는 최대 경사각 (예: 45도)
// cos(45도) 값은 약 0.707
const float WalkableFloorThreshold = FMath::Cos(FMath::DegreesToRadians(45.0f));
if (UpDot >= WalkableFloorThreshold)
{
// UpDot이 0.707에서 1.0 사이면 '바닥'으로 판단
UE_LOG(LogTemp, Log, TEXT("결과: 바닥 (캐릭터 이동 가능)"));
}
else if (UpDot > -0.1f && UpDot < WalkableFloorThreshold)
{
// UpDot이 0 근처면 '벽'으로 판단
UE_LOG(LogTemp, Log, TEXT("결과: 벽 (이동 차단 또는 벽타기 가능)"));
}
else
{
// UpDot이 음수면 '천장'
UE_LOG(LogTemp, Log, TEXT("결과: 천장"));
}'수업 > TA' 카테고리의 다른 글
| TA 6강 / 디자인 기초 1, 2 (0) | 2026.07.10 |
|---|---|
| TA 5강 / 기초 물리 (0) | 2026.07.02 |
| TA 3강 / 좌표계, Transform, 이동, 회전, 스케일 (0) | 2026.06.25 |
| TA 2강 / Vector (0) | 2026.06.19 |
| TA 1강 / TA이해하기 (0) | 2026.06.11 |