[UE4] 두개의 벡터 사이에 로테이션
#언리얼4 공부중 / UE4 버젼: 4.22.3
좌표 시스템이 아래와 같고,더미 캐릭터를 XY plane 위에서 Z축을 중심으로 로테이션을 시켜보려고 한다.
모델의 forward vector로 부터 A 벡터까지 로테이션을 해보면,
Dot product를 구하여 두 벡터 사이의 각도를 구해보았다. Dot Product는 wiki에서 잘 설명되어 있는데, 대략 공식은 다음과 같다.
\[\] \[ a \cdot b = \| a \| \| b \| \cos \theta \]
위의 공식을 이용하여, 각도를 구하려면, (두개의 벡터는 Unit Vector(단위벡터)로 길이는 1로 가정하자. \[ \| a \| = \| b \| = 1 \] )
\[ \cos \theta = \frac{ a \cdot b }{ \| a \| \| b \| } \]
\[ \theta = \arccos( a \cdot b ) \]
코드를 통해 각도를 구해보자.
auto forwardVect = GetActorForwardVector(); // forward 벡터
FVector A(-0.8f, 0.7f, 0); // A 벡터
A.Normalize();
float dot = FVector::DotProduct(forwardVect, A);
float angle = FMath::RadiansToDegrees(FMath::Acos(dot));
FMath::Acos를 통해 얻은 값은 Radian값이기 때문에 Degree로 변환이 필요하고, FMath::RadiansToDegrees를 통해 얻을 수 있다.
이제 Degree 값을 얻었기 때문에, 로테이션만 시키면 되는데, 회전 방향의 설정이 필요하다. 왼쪽이냐 오른쪽이냐. Cross Product벡터곱)을 통하여 어느 방향인지 찾아보았다. Cross Product에 대한 것은 wiki에 잘 나와있다. 오른손 법칙을 사용하면, Cross Product의 방향을 쉽게 알 수 있는데, 언리얼은 왼손 좌표계를 사용하므로, 집게 손가락을 첫번째 벡터 (forward)로, 중지를 두번째 벡터 (A)로 가리키면, 엄지 손가락이 가리키는 방향이 Cross Product의 방향이 된다.
위에 코드에 연결해보면,
FVector crossPrdt = FVector::CrossProduct(forwardVect, A);
float delta = GetWorld()->DeltaTimeSeconds;
float yawDelta = 0;
if (crossPrdt.Z < 0)
{
yawDelta = angle * delta * -1;
}
else
{
yawDelta = angle * delta;
}
FRotator deltaRotation = FRotator(0, yawDelta, 0); //Yaw
AddActorWorldRotation(deltaRotation);
매 프레임마다 delta만큼을 돌려주면 원하는 방향으로 회전이 가능하다. 다른 방식이 있는지는 더 공부해 봐야 알 것 같다..