アンリアルでは、
Unity3Dでは、とてもシンプルです。 1行のコードです( source ):
transform.LookAt(target, Vector3.up);
ブループリントには、Nodeと呼ばれる「Find Look at Rotation」があります。問題は、アップベクトルパラメーターがないため、ターゲットの近くにいるときに、不要なロール回転が発生する可能性があることです。
では、Unity LookAtに相当するものをアンリアルブループリントで作成するにはどうすればよいですか?
私はここで見つけた解決策を変更しました:
ソースアクターは、zベクトル(Unrealのアップベクトル)でターゲットを探していました。 Unrealでは、フォワードベクトルがx軸であるため、これをxベクトルに変更しました。
LookAtパラメータは、見たいアクター(ターゲット)の位置です。 UpDirectionは、ソースのアップベクトルと一致させるターゲットのアップベクトルです。
ソースのC++コードで呼び出される以下の関数によって返されるFRotator値でソースの回転を設定するだけです。
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);
}
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);
}
私はアンリアルに慣れていませんが、基本的にはこれを見てください:
yourLocation-target locationこれはターゲットへのベクトルであり、これを行う必要があります
cosInvert((a*b)/|a|*|b|)
これはあなたが見るべき角度を与えます
これで、オブジェクトの回転に設定する3つの角度があります。