Unity Quaternion.LookRotation

transform.LookAt()과 Quaternion.LookRotation()는 기능적으로 “오브젝트가 특정 방향(또는 목표 지점)을 향하도록 하는 회전”을 정의한다는 점에서는 동일한 개념이나, transform.LookAt() 메서드는 목표지점을 바라보도록 오브젝트를 회전, Quaternion.LookRotation() 메서드는 해당 회전을 나타내는 쿼터니언을 생성.


Vector3 targetDir = target.position - transform.position;
Quaternion targetRot = Quaternion.LookRotation(targetDir);
transform.rotation = targetRot;

transform.LookAt(target);
// 는 아래와 같음
transform.rotation = Quaternion.LookRotation(target.position - transform.position, Vector3.up);

void LookAt(Vector3 worldPosition, Vector3 worldUp = Vector3::up)
{
Vector3 forward = worldPosition - GetPosition();
Quaternion rot = Quaternion::LookRotation(forward, worldUp);
SetRotation(rot);
}

public static Quaternion LookRotation(Vector3 forward, [DefaultValue("Vector3.up")] Vector3 upwards)
{
return Quaternion.INTERNAL_CALL_LookRotation(ref forward, ref upwards);
}
[ExcludeFromDocs]
public static Quaternion LookRotation(Vector3 forward)
{
Vector3 up = Vector3.up;
return Quaternion.INTERNAL_CALL_LookRotation(ref forward, ref up);
}

// from http://answers.unity3d.com/questions/467614/what-is-the-source-code-of-quaternionlookrotation.html
private static Quaternion INTERNAL_CALL_LookRotation(ref Vector3 forward, ref Vector3 up)
{

forward = Vector3.Normalize(forward);
Vector3 right = Vector3.Normalize(Vector3.Cross(up, forward));
up = Vector3.Cross(forward, right);
var m00 = right.x;
var m01 = right.y;
var m02 = right.z;
var m10 = up.x;
var m11 = up.y;
var m12 = up.z;
var m20 = forward.x;
var m21 = forward.y;
var m22 = forward.z;

float num8 = (m00 + m11) + m22;
var quaternion = new Quaternion();
if (num8 > 0f)
{
var num = (float)Math.Sqrt(num8 + 1f);
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 quaternion;
}
if ((m00 >= m11) && (m00 >= m22))
{
var num7 = (float)Math.Sqrt(((1f + m00) - m11) - m22);
var 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 quaternion;
}
if (m11 > m22)
{
var num6 = (float)Math.Sqrt(((1f + m11) - m00) - m22);
var 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 quaternion;
}
var num5 = (float)Math.Sqrt(((1f + m22) - m00) - m11);
var 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 quaternion;
}
CategoriesCG