Как я могу создать эквивалент Unity LookAt в Unreal Blueprint? - PullRequest
2 голосов
/ 06 ноября 2019

В Unreal я хочу, чтобы

  1. вращал актера, где прямой вектор указывает на текущую позицию цели,
  2. , чтобы убедиться, что вектор роста моего актера совпадает сверхний вектор моей цели

В Unity3D это очень просто. Это одна строка кода ( source ):

transform.LookAt(target, Vector3.up);

В чертеже есть узел под названием «Найти взгляд на вращение». Проблема в том, что нет параметра вектора Up, поэтому, когда вы находитесь рядом с целью, вы можете иметь нежелательное вращение рулона.

Итак, как я могу создать эквивалент Unity LookAt в Unreal blueprint?

Ответы [ 3 ]

1 голос
/ 06 ноября 2019

Вы можете использовать Make Rot From XZ, чтобы сделать это довольно легко:

blueprint implementation

И для значения единицы по умолчанию worldUp, вы должны использовать(0,0,1) для этого.

Вызов его на тике с кубом (показаны направления вперед и вверх) как LookingActor, положение позиции персонажа (манекена) игрока как TargetPosition, и (0,0,1) какWorldUp дает такой результат:

animation showing block facing mannequin


И если вы предпочитаете убрать определение функции в C ++:

void UMyBlueprintFunctionLibrary::MyLookAt(AActor LookingActor, FVector TargetPosition, 
        FVector WorldUp = FVector::UpVector)
{
    FVector Forward = TargetPosition - LookingActor.GetActorLocation();
    FRotator Rot = UKismetMathLibrary::MakeRotFromXZ(Forward, WorldUp);
    LookingActor.SetActorRotation(Rot, true);
}
1 голос
/ 06 ноября 2019

Я изменил решение, которое нашел здесь:

https://forums.unrealengine.com/development-discussion/c-gameplay-programming/1482788-posting-the-source-code-for-lookrotation-for-those-who-need-it

Исходный актер искал цель с его вектором z (Up vector in Unreal). Я изменил его на вектор x, потому что в Unreal прямой вектор - это ось x.

Параметр lookAt - это позиция актера, на которого вы хотите посмотреть (цель). UpDirection - это вектор вверх цели, который вы хотите сопоставить с вектором вверх источника.

Просто установите вращение источника с помощью значения FRotator, возвращаемого функцией ниже, вызываемой в коде C ++источник:

FRotator MyLookRotation(FVector lookAt, FVector upDirection)
{
    FVector forward = lookAt - GetActorLocation();
    FVector up = upDirection;


   forward = forward.GetSafeNormal();
   up = up - (forward * FVector::DotProduct(up, forward));
   up = up.GetSafeNormal();

   ///////////////////////


   FVector vector = forward.GetSafeNormal();
   FVector vector2 = FVector::CrossProduct(up, vector);
   FVector vector3 = FVector::CrossProduct(vector, vector2);
   float m00 = vector.X;
   float m01 = vector.Y;
   float m02 = vector.Z;
   float m10 = vector2.X;
   float m11 = vector2.Y;
   float m12 = vector2.Z;
   float m20 = vector3.X;
   float m21 = vector3.Y;
   float m22 = vector3.Z;

   float num8 = (m00 + m11) + m22;
   FQuat quaternion = FQuat();

   if (num8 > 0.0f)
   {
     float num = (float)FMath::Sqrt(num8 + 1.0f);
     quaternion.W = num * 0.5f;
     num = 0.5f / num;
     quaternion.X = (m12 - m21) * num;
     quaternion.Y = (m20 - m02) * num;
     quaternion.Z = (m01 - m10) * num;
     return FRotator(quaternion);
   }

   if ((m00 >= m11) && (m00 >= m22))
   {
     float num7 = (float)FMath::Sqrt(((1.0f + m00) - m11) - m22);
     float num4 = 0.5f / num7;
     quaternion.X = 0.5f * num7;
     quaternion.Y = (m01 + m10) * num4;
     quaternion.Z = (m02 + m20) * num4;
     quaternion.W = (m12 - m21) * num4;
     return FRotator(quaternion);
   }

   if (m11 > m22)
   {
     float num6 = (float)FMath::Sqrt(((1.0f + m11) - m00) - m22);
     float num3 = 0.5f / num6;
     quaternion.X = (m10 + m01) * num3;
     quaternion.Y = 0.5f * num6;
     quaternion.Z = (m21 + m12) * num3;
     quaternion.W = (m20 - m02) * num3;
     return FRotator(quaternion);
   }

   float num5 = (float)FMath::Sqrt(((1.0f + m22) - m00) - m11);
   float num2 = 0.5f / num5;
   quaternion.X = (m20 + m02) * num2;
   quaternion.Y = (m21 + m12) * num2;
   quaternion.Z = 0.5f * num5;
   quaternion.W = (m01 - m10) * num2;


   return FRotator(quaternion);
}

enter image description here

0 голосов
/ 06 ноября 2019

Я не знаком с нереальным, но в основном это выглядит так:

yourLocation-target location это вектор к цели, тогда вы должны сделать это

cosInvert((a*b)/|a|*|b|)

thisдаст вам угол, на который вы должны смотреть

  • a будет к целевому углу
  • и b будет (0,0,1), (0,1,0), (1,0,0)

Теперь у вас есть 3 угла для поворота вашего объекта.

...