2022. 8. 15. 11:16ㆍ유니티 unity
Unity 회전에 대해서 알아보면 오일러와 쿼터니언이 있습니다.
오일러(Euler)는 x, y, z 3개의 축을 기준으로 0~360도만큼 회전시키는 좌표계입니다.
그런데 오일러에게는 짐벌락 현상이라는 단점이 있어서 그것을 보완하기 위해서 쿼터니언이 생겼습니다.
짐벌락 현상이란 같은 방향으로 오브젝트의 두 회전축이 겹치는 현상입니다.
https://www.youtube.com/watch?v=zc8b2Jo7mno
유니티는 인스펙터로는 오일러 내부적으로 쿼터니언으로 돌아간다고 생각하면 됩니다.
쿼터니언이란 x,y,z,w 4개의 로 이루어졌으며 각각 숫자는 축이나 각도가 아니라 하나의 벡터와 하나의 스칼라를 의미합니다. 세 개의 숫자가 동시에 변하기 때문에 짐벌락 현상이 발생하지 않습니다.
오일러의 장점은 직관적으로 보기 쉬움 단점은 짐벌락 현상이 있음
쿼터니언의 장점은 짐벌락 현상이 없음 단점은 직관적으로 이해하기 힘듦
2022.2 기준입니다
https://docs.unity3d.com/2022.2/Documentation/ScriptReference/Quaternion.html
Static Properties(정적 속성)
identity (Quaternion.identity) 읽기 전용
회전 없음 ( 회전 기본값)
사용법
transform.rotation = Quaternion.identity;
public static Quaternion identity
{
[MethodImpl((MethodImplOptions) 256)] get => Quaternion.identityQuaternion;
}
private static readonly Quaternion identityQuaternion = new Quaternion(0.0f, 0.0f, 0.0f, 1f);
Properties(속성)
eulerAngles (Quaternion.eulerAngles)
쿼터니언을 오일러로 변환시킵니다.
private void Start()
{
Quaternion myRotation = Quaternion.identity;
myRotation.eulerAngles = new Vector3(150, 35, 45);
Debug.Log(myRotation.eulerAngles);
// 결과창 : (30.0, 215.0, 225.0)
}
public Vector3 eulerAngles
{
[MethodImpl((MethodImplOptions) 256)] get => Quaternion.Internal_MakePositive(Quaternion.Internal_ToEulerRad(this) * 57.29578f);
[MethodImpl((MethodImplOptions) 256)] set => this = Quaternion.Internal_FromEulerRad(value * ((float) Math.PI / 180f));
}
normalized (Quaternion.normalized)
쿼터니언을 정규화시킵니다. 현재의 쿼터니언은 변경되지 않고 새로운 정규화된 쿼터니언이 반환됩니다.
원래 쿼터니언을 정규화시키려면 Normalize를 사용하면 됩니다.
쿼터니언이 정규화되기에 너무 작을 경우 identity를 반환합니다.
Public Methods(메소드)
SetFromToRotation (public void SetFromToRotation(Vector3 fromDirection, Vector3 toDirection))
fromDirection에서 toDirection까지 회전하는 Quaternion를 반환합니다.
Quaternion m_MyQuaternion;
float m_Speed = 1.0f;
Vector3 m_MousePosition;
void Start()
{
m_MyQuaternion = new Quaternion();
}
void Update()
{
//마우스 위치 가져오기
m_MousePosition = Input.mousePosition;
m_MousePosition.z = 50.0f;
//마우스 월드공간으로 변환
m_MousePosition = Camera.main.ScreenToWorldPoint(m_MousePosition);
//게임오브젝트 위치에서 마우스 위치러 쿼터니언 회전을 설정
m_MyQuaternion.SetFromToRotation(transform.position, m_MousePosition);
//이동부분
transform.position = Vector3.Lerp(transform.position, m_MousePosition, m_Speed * Time.deltaTime);
//회전시킵니다.
transform.rotation = m_MyQuaternion * transform.rotation;
}
public void SetFromToRotation(Vector3 fromDirection, Vector3 toDirection) => this = Quaternion.FromToRotation(fromDirection, toDirection);
ToAngleAxis(public void ToAngleAxis(out float angle, out Vector3 axis))
축과 각도를 반환합니다.
void Start()
{
float angle = 0.0f;
Vector3 axis = Vector3.zero;
transform.rotation.ToAngleAxis(out angle, out axis);
}
public void ToAngleAxis(out float angle, out Vector3 axis)
{
Quaternion.Internal_ToAxisAngleRad(this, out axis, out angle);
angle *= 57.29578f;
}
Static Methods(정적 메소드)
Angle (public static float Angle(Quaternion a, Quaternion b))
a와 b의 두 회전 사이의 각도를 반환합니다.
public static float Angle(Quaternion a, Quaternion b)
{
float num = Mathf.Min(Mathf.Abs(Quaternion.Dot(a, b)), 1f);
return Quaternion.IsEqualUsingDot(num) ? 0.0f : (float) ((double) Mathf.Acos(num) * 2.0 * 57.2957801818848);
}
AngleAxis (public static Quaternion AngleAxis(float angle, Vector3 axis))
axis 주위를 angle만큼 회전한 쿼터니언을 반환합니다.
void Start()
{
// Vector3.up 기준으로 30도만큼 회전합니다.
transform.rotation = Quaternion.AngleAxis(30, Vector3.up);
}
public static Quaternion AngleAxis(float angle, Vector3 axis)
{
Quaternion ret;
Quaternion.AngleAxis_Injected(angle, ref axis, out ret);
return ret;
}
Dot (public static float Dot(Quaternion a, Quaternion b))
a와 b 쿼터니언의 내적을 구합니다.
public static float Dot(Quaternion a, Quaternion b) => (float) ((double) a.x * (double) b.x + (double) a.y * (double) b.y + (double) a.z * (double) b.z + (double) a.w * (double) b.w);
Euler (public static Quaternion Euler(float x, float y, float z))
오일러를 쿼터니언으로 변환시킵니다.
void Start()
{
// y값이 30도 회전한 쿼터니언
Vector3 rotationVector = new Vector3(0, 30, 0);
Quaternion rotation = Quaternion.Euler(rotationVector);
}
FromToRotation (public static Quaternion FromToRotation(Vector3 fromDirection, Vector3 toDirection))
fromDirection에서 toDirection으로 회전한 쿼터니언을 반환합니다.
void Start()
{
// vector3.up에서 transform.forward 로 회전한 각도로 현재 각도를 변환합니다.
transform.rotation = Quaternion.FromToRotation(Vector3.up, transform.forward);
}
Inverse (public static Quaternion Inverse(Quaternion rotation))
역을 반환합니다 반대를 반환
void Update()
{
transform.rotation = Quaternion.Inverse(target.rotation);
}
Lerp (public static Quaternion Lerp(Quaternion a, Quaternion b, float t))
선형 보간합니다
LerpUnclamped (public static Quaternion LerpUnclamped(Quaternion a, Quaternion b, float t))
선형 보간 제한치 없음
LookRotation (public static Quaternion LookRotation(Vector3 forward, Vector3 upwards = Vector3.up))
지정된 forward와 upwards 방향으로 회전하는 쿼터니언을 반환합니다.
public Transform target;
void Update()
{
Vector3 relativePos = target.position - transform.position;
// relativePos 를 바라봅니다. 두번째는 기본적으로 Vector3.up이 들어가있습니다.
Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up);
transform.rotation = rotation;
}
forward로 바라보는 함수로 자주 쓰이는 함수입니다.
Normalize (public static Quaternion Normalize(Quaternion q))
정규화시킵니다.
RotateTowards (public static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta))
from에서 to를 향해서 maxDegreesDelta 속도로 회전하는 쿼터니언을 반환합니다.
// 회전시킬려는 대상
public Transform target;
// 속도
private float speed = 1f;
void Update()
{
// 속도
var step = speed * Time.deltaTime;
// step속도만큼 회전합니다. (점점 가까워짐)
transform.rotation = Quaternion.RotateTowards(transform.rotation, target.rotation, step);
}
Slerp (public static Quaternion Slerp(Quaternion a, Quaternion b, float t))
구면 선형 보간
SlerpUnclamped (public static Quaternion SlerpUnclamped(Quaternion a, Quaternion b, float t);)
구면 선형 보간 제한치 없음
ToAngleAxis (public void ToAngleAxis(out float angle, out Vector3 axis);)
축과 각도를 out인자 를 통해 반환하는 함수입니다.
'유니티 unity' 카테고리의 다른 글
유니티(Unity) Job 시스템 사용법-1 (0) | 2022.08.23 |
---|---|
Unity / 베지어곡선이용해서 라인렌더로 곡선 그리기 (0) | 2022.08.16 |
Unity Unitask 사용법 (0) | 2022.08.10 |
unity(유니티) vector 함수 전부 알기 (0) | 2022.08.03 |
Unity로 node.js WebSocket 통신하기 (socket.io,Mysql 이용해서 붐버맨 만들기)-4 (0) | 2022.07.30 |