Unity-#6. 방향,크기,회전(Vector, Qunterion)

CHO WanGi·2024년 4월 8일

Unity

목록 보기
6/13

Vector

Unity에선 벡터값을 공간상의 화살표 로 사용
(10,5,0)은 오른쪽으로 10, 위로 5만큼 이동하는 화살표
게임개발에서 벡터는 위치, 방향, 속도를 나타내는 데 사용됨

Vector3

3D Vector 인 vector3 타입, 무조건 x,y,z 에 대응하는 세 원소를 가져야함.
즉 3D 공간에서의 x,y,z 좌표를 표현함

벡터를 이처럼 공간에서 물체의 좌표를 표현하는데 사용할 수 있지만,
출발점이 정의되지 않았기 때문에 절대적인 위치가 아님.

-> 어떤 뱡향으로 얼마만큼 가고 있는지 표현하는 것

절대위치와 상대 위치

벡터는 방향과 크기를 가짐,
크기는 길이로 비유가능

  • 상대좌표 : 현재 좌표에서 (x,y,z) 만큼 더 가려고 하는 것
    => 상대적 방향과 크기(길이) 표현가능
  • 절대좌표 : 게임 세상 속 좌표가 (x, y, z)

벡터의 크기

만약 2D 벡터(-3,4)가 있을때, 방향과 크기를 갖는다.
벡터의 크기는 피타고라스 정리를 활용하여,
x2+y2\sqrt{x^{2} + y^{2}} 로 구할 수 있다.
따라서 2D 벡터 (-3,4)의 크기는 5

벡터의 크기는 또한 화살표의 길이에 대응, 따라서 음수가 될 수 없음

  • 벡터 값 수식 표현
    절대값 기호를 통하여 X\left | X \right |로 표현
    ex. A(-1.5,2) => A(1.5,2)=2.5\left | A(-1.5,2) \right |= 2.5

벡터의 스칼라 곱

만약 A(-6,8)과 B(-3,4) 두 벡터가 존재한다면,
A 벡터의 크기는 10, B 벡터의 크기는 5
개별 원소 모두 -3,4의 2배일 경우

벡터 A는 벡터 B의 2배곱
즉 이 2배에 해당하는 것이 바로 스칼라 곱

따라서 벡터의 스칼라 곱은 벡터의 각 원소에 개별적으로 곱셈이 적용
각 원소와 크기가 스칼라 곱 만큼 증가

-> 즉, 기존 벡터를 잡아서 늘리거나 줄이는 배율
다만, 벡터의 방향은 변경할 수 없음

방향벡터

벡터 값은 속도로 해석하면, 벡터의 화살표 방향은 이동방향을, 화살표 길이는 속력(이동 거리)로 표현이 가능

방향 벡터는 크기가 1인 벡터, 정규화된 벡터 라고 부름.
크기가 1이라 방향은 동일하지만, 크기가 서로 다른 벡터를 비교하는 기준으로 활용이 가능함.

순수하게 방향만 나타냄.

따라서 어떤 벡터의 방향과 크기(속력)을 직관적으로 표현하기 위해선
방향 벡터 * 스칼라 곱 으로 표현이 가능함.

벡터 연산

  • 덧셈
    두 벡터 덧셈시 같은 자리의 성분끼리 합쳐짐

    A와 B가 이동을 표현하는 벡터라면,
    A+B는 A만큼 이동한 다음, 연속해서 B만큼 더 이동하는 것을 표현함

  • 뺄셈
    어떤 수에서 다른 수에 도달하기 위한 거리와 방향을 나타냄

    B-A는 A에서 B까지의 간격 = A에서 B까지의 방향과 거리
    즉, 현재 위치에서 도착 지점까지의 방향과 거리가 나옴

ex. Enemy(1,3), Player(-2,8)일때, 적이 이동할 방향과 거리는 뺄셈을 이용하여 (-3,5) 임을 알 수 있다.

cf> 이동할 방향은 (-3,5), 방향벡터는(-0.5,0.9), 이동할 거리는 크기인 약 5.83...

벡터의 내적(점연산)

백터 B의 크기 변화가 벡터 A의 시선에선 얼만큼 해당하는지

ABA \cdot B 로 표현
두 물체간 각도가 얼마만큼 벌어졌는지 파악 가능

벡터의 외적(교차곱)

AXBA X B 로 표현
어떤 표면에 수직인 방향

Unity C# Vector

Vector 타입 생성

new 연산자로 생성, 각 원소 개별 접근 및 수정 가능

Vector 3 a = new Vector3(1,1,1);
a.x = 2
a.y = 2
a.z = 2

구조체

Vector 타입은 클래스가 아니고 구조체로 선언되어
변수가 값 자체로 동작
따라서 참조 타입이 아니기때문에 mutation 이 일어나지 않는다.

Vector 3 연산

  • 스칼라 곱
    Vector3 * scala

  • 덧셈, 뺄셈
    Vector 3 +/- Vector 3

  • 벡터 정규화(방향벡터로 만들기)
    Vector3.normalized

  • 벡터의 크기(길이)
    Vector3.magnitude

  • 벡터의 내적
    Vector3.Dot(a, b)

  • 벡터의 외적
    Vector3.Cross(a,b)

Vector3 응용

  • 두 지점 사이 거리 구하기
Vector3 curpos = new Vector3(1,0,1);
Vector3 destpos = new Vector3(5,3,5);

Vector3 delta = destpos - curpos
// curpos~destpos의 거리(크기)
float distance = delta.magnitude

//동일한 값을 이렇게도 표현 가능
float distance = Vector3.Distance(curpos, destpos);
  • 현재 위치서 목적지로 향하는 방향
    즉 방향벡터를 구하는 방법은 destpos - curpos를 정규화한 벡터
Vector3 direction = (destpos - curpos).normalized;

만약 현재 위치서 목적지방향으로 10만큼 이동한 위치를 구하려면

Vector3 newpos = curpos + direction + 10

Quaternion

원소로 x,y,z 이외에 w를 갖는 값(사원수)

Transform 컴포넌트의 Rotation 값은 Quaternion
따라서 회전을 수정하는 부분에서 Vertor3로 받으면 에러가 발행함

transform.rotation = new Vector3(1,1,1); // X
Quaternion.rotation = Quaternion.Euler(new Vector3(1,1,1)); // 0

다만, 이러면 너무 직관적이지 않기 때문에 유니티가 Vector3 로 다루도록 배려함.

cf> 3D 물체의 3D 회전을 나타내는 표현을 오일러 각 이라고 함.

쿼터니언 연산

  • 새로운 회전 데이터 생성
Quaternion.rotation = Quaternion.Euler(new Vector3(1,1,1)); 
  • 회전을 Vector3(오일러각)으로 가져오기
    eulerAngles 활용
Quaternion.rotation = Quaternion.Euler(new Vector3(1,1,1)); 
Vector3 eulerRotation = rotation.eulerAngles;
  • 현재 회전에서 "더" 회전하기
    (30,0,0) 만큼 회전한 상태애서 (0,60,0) 만큼 더 회전한 상태를 표현
    다만, 이를 합쳐서 (30,60,0) 회전과 다르다는 것을 반드시 유의할 것!
Quaternion a = Quaternion.Euler(30,0,0);
Quaternion b = Quaternion.Euler(0,60,0);

Quarternion rotation = a * b;
profile
제 Velog에 오신 모든 분들이 작더라도 인사이트를 얻어가셨으면 좋겠습니다 :)

0개의 댓글