1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | FVector Dest = FVector(GoalPosition.X, GoalPosition.Y, 0.0f); FVector Start = FVector(GetTransform().GetLocation().X, GetTransform().GetLocation().Y, 0.0f); FVector dir = Dest - Start; GoalDirection = dir.SafeNormal(); //노말라이징한 두개의 백터를 dot한다. //여기서 축을 Z축으로 하기 위해 두백터의 Z값을 0.0f로 넣어 주었다. float dot = FVector::DotProduct(FVector::ForwardVector, GoalDirection); float AcosAngle = FMath::Acos(dot); // dot한 값을 아크코사인 계산해 주면 0 ~ 180도 사이의 값 (0 ~ 1)의 양수 값만 나온다. float angle = FMath::RadiansToDegrees(AcosAngle); //그값은 degrees 값인데 이것에 1라디안을 곱해주면 60분법의 도가 나온다. //여기서 두 백터를 크로스 하여 회전할 축을 얻게 된다. //이 크로스 백터는 Axis회전의 회전축이 되며 , 그 양수 음수로 회전 방향 왼쪽(음수), 오른쪽(양수)를 알수 있다. FVector cross = FVector::CrossProduct(FVector::ForwardVector, GoalDirection); FString lr = "center //"; if(cross.Z > 0) { lr = "Right //"; TurnAngle = angle; } else if (cross.Z < 0) { lr = "Left //"; //TurnAngle = 360 - angle; //360에서 뺴게되면 양수로 각을 리턴하게 된다. TurnAngle = -angle; } FString str = FString::Printf(TEXT("AcosAngle : %f, angle : %f // "), AcosAngle, angle); //출력해보기 GEngine->AddOnScreenDebugMessage(-1, 100.0f, FColor::Green, str+ lr + GoalDirection.ToString()); | cs |
*여기서 아크코사인이 사용 되었는데 그것은 물체가 왼쪽에 있을 경우 상식적으로 왼쪽으로 회전해야 하는데,
그냥 코사인 값을 쓸 경우 오른쪽방향으로 회전하는 것이라 오래 걸린다. (행성의 자전이나 단방향 회전하는 물체 등에는 코사인으로 하면될것이다)
위코드는 forward백터를 기준으로 회전하는 것이고
아래 코드는 내가 현재 가지고 있는 방향으로 부터 다음 방향을 구하는 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | void ARollingBall::SetNewGoalDirection() { //일단 기존에 가지고 있던 Direction과 Angle을 이전 값으로 해준다. PrevGoalDirection = CurrentGoalDirection; PrevTurnAngle = GetTransform().GetRotation().Euler().Z; //먼저 현재 지점에서부터 목표지점을 향한 Direction을 구한다. FVector Dest = FVector(GoalPosition.X, GoalPosition.Y, 0.0f); FVector Start = FVector(GetTransform().GetLocation().X, GetTransform().GetLocation().Y, 0.0f); FVector newDir = Dest - Start; CurrentGoalDirection = newDir.GetSafeNormal(); //노말라이징한 두개의 백터를 dot한다. //여기서 축을 Z축으로 하기 위해 두백터의 Z값을 0.0f로 넣어 주었다. float dot = FVector::DotProduct(PrevGoalDirection, CurrentGoalDirection); float AcosAngle = FMath::Acos(dot); // dot한 값을 아크코사인 계산해 주면 0 ~ 180도 사이의 값 (0 ~ 1)의 양수 값만 나온다. float angle = FMath::RadiansToDegrees(AcosAngle); //그값은 degrees 값인데 이것에 1라디안을 곱해주면 60분법의 도가 나온다. //여기서 두 백터를 크로스 하여 회전할 축을 얻게 된다. //이 크로스 백터는 Axis회전의 회전축이 되며 , 그 양수 음수로 회전 방향 왼쪽(음수), 오른쪽(양수)를 알수 있다. FVector cross = FVector::CrossProduct(PrevGoalDirection, CurrentGoalDirection); FString lr = "center //"; if(cross.Z > 0) { lr = "Right //"; NextTurnAngle = angle; } else if (cross.Z < 0) { lr = "Left //"; //NextTurnAngle = 360 - angle; //360에서 뺴게되면 양수로 각을 리턴하게 된다. NextTurnAngle = -angle; } } | cs |
'프로그래밍 > Unreal Engine4' 카테고리의 다른 글
현재 레벨에 있는 다른 Actor의 C++클래스 연결하기. (0) | 2016.04.20 |
---|---|
언리얼 C++ 컨텐츠 브라우저에서 제거 하는법 (0) | 2016.04.19 |
BoxComponent안의 랜덤한 포지션 받아오는 방법 (0) | 2016.04.18 |
언리얼의 좌표계와 회전 (2) | 2016.04.18 |
UStaticMeshComponent 디테일 편집 가능하게 만들기 (0) | 2016.04.18 |