KoreanFoodie's Study

9. 벡터(Vector)와 쿼터니언 : 유니티 튜토리얼 본문

Game Dev/Unity : Tutorial

9. 벡터(Vector)와 쿼터니언 : 유니티 튜토리얼

GoldGiver 2021. 9. 5. 11:11

벡터

벡터는 방향과 크기를 가진다. 벡터 (1, 0, 2)이 있을때, 해당 벡터의 크기는  sqrt(1^2 + 2^2)이 된다.

유니티는 Vector2, Vector3, Vector4 타입을 지원한다. 새로운 벡터를 만들 때는 생성자를 호출하면 된다.

// Vector는 클래스가 아니라 구조체이다!
public struct Vector3 
{
	public float x;
    public float y;
    public float z;
    
    // Vector3 내부 코드
}

Vector3 a = new Vector3(0, 0, 0);
Vector3 b = a;
b.x = 100;

 

벡터의 연산

내적과 외적의 의미를 이해하는 것이 중요하다.

백터의 내적은 Dot Product라고하는데, a · b 라고 하면, 벡터 b를 a의 지평선으로 끌어내린다는 의미이다! 이때 값은 |a| |b| cosθ 가 되는데, 해당 각도가 벌어질 수록 b가 a의 지평선에 내려오는 길이가 짧은 것을 이용할 수 있다.

벡터의 외적은 Cross Product라고 하는데, 두 벡터 모두에 수직인 벡터를 구하는 것이다. 그럼 이제 코드를 보자.

// 벡터 정규화 (방향 벡터로 만들기)
Vector3 a = new Vector3(3, 3, 3);
Vector3 b = a.normalized; // b는 대략 (0.6, 0.6, 0.6)이 됨

// 벡터의 크기
Vector3 a = new Vector3(3, 3, 3);
float b = a.magnitude; // b는 대략 5.19... 가 됨

// 벡터의 내적
Vector3 a = new Vector3(0, 1, 0); // 위쪽
Vector3 b = new Vector3(1, 0, 0); // 오른쪽
float c = Vector3.Dot(a, b); // 수직인 벡터끼리 내적하면 결과는 0

// 벡터의 외적
Vector3 a = new Vector3(0, 0, 1); // Z
Vector3 b = new Vector3(1, 0, 0); // X
// 외적 결과 C는 X, Z에 수직인 Y 방향벡터
Vector3 c = Vector3.Cross(a, b); // c는 (0, 1, 0)

벡터의 외적

벡터의 응용

Vector3 currentPos = new Vector3(1, 0, 1);
Vector3 destPos = new Vector3(5, 3, 5);

// currentPos 에서 destPos로 향하는 벡터
Vector3 delta = currentPos - destPos;

// currentPos에서 destPos까지의 거리
float distance = delta.magnitude;
// 혹은...
distance = Vector3.Distance(currentPos, destPos);

 

쿼터니언

transform.position = new Vector3(0, 0, 10);
transform.localScale = new Vector3(1, 1, 1);

// rotation 은 Vector3 타입이 아닌 Quaternion 타입이므로 에러 발생
transform.rotation = new Vector3(30, 60, 90);

rotation을 벡터 타입이 아닌 쿼터니언으로 표시한 것은 짐벌락 현상을 피하기 위해서이다!!

 

그럼 쿼터니언 예제를 보자.

// 새로운 쿼터니언 생성(오일러각)
Quaternion.Euler(Vector3);

// 회전을 표현하는 쿼터니언 회전 데이터 생성 및 대입
Quaternion rotation = Quaternion.Euler(new Vector3(0, 60, 0));
transform.rotation = rotation;

// Vector3 타입의 값으로 (0, 60, 0)이 나온다 : 오일러각으로 표현
Vector3 eulerRotation = rotation.eulerAngles;

// x축으로 30도, y축으로 60도 회전하기!
Quaternion a = Quaternion.Euler(30, 0, 0);
Quaternion b = Quaternion.Euler(0, 60, 0);

// a만큼 회전한 상태에서 b만큼 더 회전한 회전값을 표현 (행렬연산)
Quaternion rotation = a * b;
transform.rotation = rotation;

// 아래 식은 완전 다른 의미임!
// Quaternion rotation = Quaternion.Euler(30, 60, 0)


// 추가로 쓸만한 함수 : 특정 방향을 쳐다보는 함수
Quaternion targetRotation = Quaternion.LookRotation(new Vector3(0, 60, 0));
transform.rotation = targetRotation;

 

Comments