Game/Unity

[유니티] 방향, 크기, 회전 (1)

nowkoes 2023. 2. 15. 11:36

<본 글은 레트로의 유니티 게임 프로그래밍 에센스(개정판)를 참고로 하여 작성하였습니다>


벡터 수학

벡터의 정의와 좌표의 의미

 

 유니티에서 벡터를 이해하는 것은 매우 중요하다. 벡터(Vector)란 일반적으로 크기와 방향을 가진 물리량으로 정의하지만, 세 가지 관점으로 넓혀서 정의할 수 있다.

 

  • 공간상의 화살표로서의 벡터
  • 나열된 숫자 데이터를 묶는 단위로서의 벡터
  • 벡터 연산을 만족하고 정해진 개수의 원소를 가지는 벡터

 

일반적으로 게임 개발에서 벡터는 주로 위치, 방향, 속도를 나타낼 때 사용된다. 이를테면 위치를 표현하기 위한 Vector3(0, 1, 1)은 어떤 물체가 x = 0, y = 1, z =1의 위치에 존재한다고 해석할 수 있다. 이를 유니티의 메서드인 DrawLine을 이용해 그려보자.

 

출처: https://docs.unity3d.com/kr/530/ScriptReference/Debug.DrawLine.html

 

 Debug.DrawLine()start와 end 사이를 선으로 그려주는 메서드다. 이를 이용하여 코드를 다음과 같이 작성하고 GameObject에 부착하면 움직인 거리를 시각적으로 확인할 수 있다.

 

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Test : MonoBehaviour
{
    public GameObject gameObject;
    Vector3 startPos, endPos;

    private void Start()
    {
        startPos = gameObject.transform.position;
        endPos = new Vector3(0, 1, 1);

        gameObject.transform.position = endPos;
        Debug.DrawLine(startPos, endPos, Color.red, 5f);
    }
}

 

(0,0,0)에서 (0,1,1)로 이동

 

 

 이뿐만 아니라 벡터의 값을 어떤 방향으로 얼마만큼 가고 있는지 표현할 수도 있다. 예를 들어 (0,1,1)이라는 것은 현재 좌표에서 (0,1,1)만큼 더 간다는 의미와, 나의 위치가 (0,1,1)이라는 의미로 나뉜다.

 

 이를 그림으로 표현하면 다음과 같다.

 

절대 좌표의 의미에서 (0,1,1)과 상대 좌표의 의미에서 (0,1,1)

 

 위의 동영상에서 물체는 (0,0,0)에서 (0,1,1)로 이동하였다(절대 좌표의 의미). 여기서 코드를 게임 월드 속에서 (0,1,1)로 이동시키는 것이 아닌, 현재 좌표에서 (0,1,1)을 더한다고 했을 때, 이때 벡터의 의미는 현재 위치에서 상대적으로 어느 방향으로 얼마만큼의 크기로 갈 것인지 표현할 수 있게 된다(상대 좌표의 의미).


벡터의 크기와 방향

 벡터는 스칼라(scalar)와 다르게 방향과 크기를 갖는 물리량이라고 했다. 그렇다면 방향과 크기를 어떻게 구할까? 벡터의 크기모든 원소를 제곱하여 더한 값의 제곱근이다. 

 

2D에서 벡터의 크기

3D에서 벡터의 크기

 

 다음과 같이 이차원 벡터 (3,4)가 있을 때, 이 벡터의 크기 |X|는 √(3*3 + 4*4) = 5가 된다. 이때 벡터의 크기는 화살표의 길이에 대응하므로 음수가 될 수 없다. 또한 방향은 같지만 크기만 다른 벡터가 존재할 수 있다.

 

 그렇다면 저 (3,4) 벡터의 방향은 어떻게 결정하는 것일까? 일단 벡터를 속도라고 생각했을 때, 벡터의 화살표 방향은 이동하려는 방향이 되고, 화살표의 길이는 속력에 대응할 것이다. 이를 직관적으로 방향과 속력을 표현하기 위해 벡터의 스칼라 곱을 이용하여 다음과 같이 표현을 한다면 파악할 수 있을 것이다.

 

  • (3,4) = (방향) x (속력) =  (방향 벡터) x (스칼라 속력)

 

 이때 스칼라 곱 x는 벡터에 배수를 취하는 숫자를 곱하는 것을 의미하며, 곱하는 수스칼라(Scalar)라고 한다. 벡터에 스칼라 곱을 적용하면 각 원소에 개별적으로 곱셉이 적용된다. 따라서 기존 벡터의 배율을 변경한다고 생각하면 된다.

 

 따라서 순수한 방향을 표현하기 위해 해당 벡터를 정규화를 할 것이다. 여기서 정규화(Normalized)크기를 1로 바꾼다고 생각하면 된다. 즉, 벡터의 시작점에서 반지름인 1인 원을 그려 원 바깥 부분을 잘라내 벡터의 크기를 1로 바꾸면 된다.

 

(3,4) = (0.71, 0.71) x 5


벡터의 연산

 벡터 간 덧셈 뺄셈이 가능하다. 이때 두 벡터를 더하면 같은 자리의 성분끼리 합쳐진다. 예를 들어 벡터 A (2,2)와 벡터 B (1,3)을 더한다고 하면 다음과 같이 A만큼 이동한 상태에서 B만큼 더 이동한다는 기하학적 의미를 갖게 된다.

 

 

 두 벡터를 뺀다는 의미는 두 벡터 사이의 간격을 구한다는 뜻이다. 즉, 두 벡터 사이의 거리와 방향을 나타내게 된다. 이를 이용하면 물체를 추적할 때 어떤 방향으로 얼마만큼 가야 하는지 알 수 있게 된다. 위의 벡터를 뺀다 (A-B)고 하면,

 


벡터의 내적과 외적

 벡터의 내적(Inner product)이란 어떤 벡터를 다른 벡터로 투영한다는 의미다. 이때 투영이란 수직으로 내린 것을 의미한다. 사실 우리가 일반적으로 알고 있는 내적은 도트 곱(dot product) 혹은 스칼라 곱(scalar product)라고 부르는 내적의 한 종류다. 이런 관점에서 두 벡터의 내적을 구한다는 것을 그림으로 표현하면 다음과 같다.

 

 

 이러한 내적은 자신과 상대방 사이의 각도가 벌어질수록 투영된 길이가 짧아지므로, 둘 사이의 각도를 구할 때 사용된다는 특징이 있다. 예를 들어 탱크의 몸체와 탱크의 포신의 간격이 얼마나 벌어졌는지, 플레이어의 시선 방향과 플레이어가 실제로 이동하는 방향의 간격이 얼마나 벌어졌는지 등을 쉽게 파악할 수 있다. 또한 내적의 결과는 위의 수식을 통해 알 수 있듯이 스칼라 값으로 나온다.

 

 벡터의 외적(Outer product)이란 두 벡터를 모두 수직으로 통과하는 벡터를 구하는 연산이며, 벡터 곱(vector product) 혹은 교차 곱(cross product)라고 부르기도 한다. 엄밀히 따지면 외적과 벡터 곱은 서로 다른 의미다. 외적(Outer prodcut)은 일반적으로 선형대수에서 두 벡터 사이의 텐서곱을 의미한다. 이에 대한 내용은 우리가 다루는 범위를 벗어나므로 생략하도록 하겠다.

 

 어쨌든 이러한 벡터 곱 연산을 하면 결괏값이 내적과 다르게 벡터로 나온다. 이러한 벡터는 어떤 표면에 수직인 방향을 의미하게 되는데, 조금 쉽게 다가가기 위해 두 벡터를 외적한 것을 그림으로 나타내보면

 

 

이렇게 된다.

 

 외적의 연산 순서를 바꾼다면 결과 벡터의 방향이 반대가 된다는 특징과, 외적을 이용하면 표면의 수직 방향을 구할 수 있다는 점 정도만 체크하고 넘어가도록 하자.

반응형