Step 1. Angle값 구하기.
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 |
Step 2. 구해진 Angle값 으로 회전하기.
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 | //먼저 받아온 앵글 값을 절대값으로 바꾼다. float absTurnAngle = FMath::Abs(TurnAngle); // 총 회전할 시간 = 최종회전각 / 초당회전 스피드 float RotationTime = absTurnAngle / TurnSpeedForDeltaTime; // 현재 회전 시간을 계속 더해준다. CurrentRotationTime += TurnDeltaTime; // 현재 lerp에 들어갈 알파값 = 현재 시간 / 총 회전할 시간 float t = CurrentRotationTime / RotationTime; //1보다 작을 경우 아직 회전중이라는 의미이다. if (t < 1) { float angle = 0.0f; //받아온 angle값이 음수일 경우 왼쪽으로 회전 양수일경우 오른쪽으로 회전하기위해 구분하여 준다. if (TurnAngle < 0) { angle = -1 * (FMath::Lerp<float, float>(0, absTurnAngle, t)) ; } else if (TurnAngle > 0) { angle = FMath::Lerp<float, float>(0, absTurnAngle, t); } RootComponent->SetWorldRotation(FRotator(0.0f, angle, 0.0f).Quaternion()); return false; } else { //시간이 1을 이상일 경우 각도를 그냥 넣어준다. RootComponent->SetWorldRotation(FRotator(0.0f, TurnAngle, 0.0f).Quaternion()); return true; } | cs |
위 코드는 0도에서 X 도로 돌아가고 다시 0도에서 X도로 돌아가는 코드
아래 코드는 현재 가지고 있는 angle에서 회전해야할 만큼 값을 더해서 회전한다.
Step 1. Angle값 구하기.
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 35 36 | bool ARollingBall::IsTurnOk() { //먼저 받아온 NextTurnAngle을 절대값으로 바꾼다. float absNextTurnAngle = FMath::Abs(NextTurnAngle); // 총 회전할 시간 = 최종회전각 / 초당회전 스피드 float RotationTime = absNextTurnAngle / TurnSpeedForDeltaTime; // 현재 회전 시간을 계속 더해준다. CurrentRotationTime += TurnDeltaTime; // 현재 lerp에 들어갈 알파값 = 현재 시간 / 총 회전할 시간 float t = CurrentRotationTime / RotationTime; //1보다 작을 경우 아직 회전중이라는 의미이다. if (t < 1) { // 이전에 즉 회전하기전 가지고 있는 Angle을 기본으로 두고 그값에 보간된 값을 더한다. float angle = PrevTurnAngle; //받아온 angle값이 음수일 경우 왼쪽으로 회전 양수일경우 오른쪽으로 회전하기위해 구분하여 준다. if (NextTurnAngle < 0) { angle += -1 * (FMath::Lerp<float, float>(0, absNextTurnAngle, t)) ; } else if (NextTurnAngle > 0) { angle += FMath::Lerp<float, float>(0, absNextTurnAngle, t); } RootComponent->SetWorldRotation(FRotator(0.0f, angle, 0.0f).Quaternion()); return false; } else { //시간이 1을 이상일 경우 각도(기존에 가지고 있던값 + 회전 해야할 값)를 그냥 넣어준다. RootComponent->SetWorldRotation(FRotator(0.0f, PrevTurnAngle + NextTurnAngle, 0.0f).Quaternion()); return true; } } | cs |
Step 2. 회전하기
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 or 5 > 코드' 카테고리의 다른 글
UE4 C++ 비주얼 스튜디오 에서 BreakPoint 사용하는법 (0) | 2016.04.25 |
---|---|
UE4 angle과 acos를 이용한 원형 회전 하기 (0) | 2016.04.25 |
UE4 블루 프린트 함수 _Implementation (0) | 2016.04.21 |
UE4 Actor의 이동 (0) | 2016.04.21 |
현재 레벨에서의 컴퍼넌트 찾는 방법. FindObject (0) | 2016.04.20 |