如何在 Unreal 蓝图中创建与 Unity LookAt 等效的内容?

pro*_*lle 6 c++ vector rotation unreal-engine4 unreal-blueprint

在虚幻中,我想要

  1. 旋转角色,使前向向量指向目标的当前位置,
  2. 确保我的演员的向上向量与我的目标的向上向量相同

在Unity3D中,这非常简单。这是一行代码(源代码):

transform.LookAt(target, Vector3.up);
Run Code Online (Sandbox Code Playgroud)

在蓝图中,有一个名为“Find Look at Rotation”的节点。问题是没有向上矢量参数,因此当您接近目标时,可能会出现不需要的滚动旋转。

那么,如何在 Unreal 蓝图中创建相当于 Unity LookAt 的功能呢?

Ruz*_*ihm 8

你可以Make Rot From XZ很容易地做到这一点:

蓝图实施

对于 的默认统一值worldUp,您可以使用(0,0,1)它。

用立方体(显示向前和向上方向)作为LookingActor,将玩家角色(人体模型)的位置作为TargetPosition,并(0,0,1)作为 ,WorldUp在刻度上调用它会产生如下结果:

动画显示面向人体模型的块


如果您宁愿隐藏 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);
}
Run Code Online (Sandbox Code Playgroud)


Émi*_*mbe 0

我修改了在这里找到的解决方案:

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

源演员正在用他的 z 向量(虚幻中的向上向量)寻找目标。我将其更改为 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);
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述