비트를 쪼개는 개발자

allen321@naver.com

게임수학

게임수학 - 벡터

MozarTnT 2024. 7. 16. 22:17
728x90
반응형

 

 

 

 

 

 

 

벡터란 ? 

 

 

  • 벡터는 물리학과 수학에서 자주 사용하는 용어이다.

 

  • 벡터는 "크기"와 "방향", 두가지를 가지는 양을 의미한다. (바람의 세기, 플레이어의 이동 방향과 속도 등)

 

  • 차원에 따라 벡터는 다르게 정의된다.

 

 

 

벡터의 특징

 

 

  • 벡터간에는 덧셈과 뺄셈이 가능하다.
void Start()
{
	Vector3 a = new Vector3(3, 4, 0);
	Vector3 b = new Vector3(-2, 2, 0);

	Vector3 r1 = a + b;
	Vector3 r2 = a - b;

	Debug.Log("r1 : " + r1);
	Debug.Log("r2 : " + r2);
}

 

 

 

 

 

 

 

 

  • Magnitude(벡터의 크기)와 distance(벡터간의 거리) 는 벡터를 뺄셈하거나 피타고라스 정리를 이용해 빗변의 길이를 계산하는 방식으로 구한다.
void Start()
{
    Vector3 a = new Vector3(3, 4, 0);
    Vector3 b = new Vector3(-2, 2, 0);

    Vector3 r1 = a + b;
    Vector3 r2 = a - b;

    float d = Mathf.Sqrt(Mathf.Pow(r2.x, 2) + Mathf.Pow(r2.y, 2) + Mathf.Pow(r2.z, 2)); // 빗변 거리로 구하기

    Debug.Log("d : " + d);
    Debug.Log("magnitude : " + r2.magnitude); // 뺄셈의 magnitude로 구하기
    Debug.Log("distance : " + Vector3.Distance(a, b)); // 벡터 2개 넣고 distance 함수 호출
}

 

 

-  위에 사용했던 벡터를 가져와서 피타고라스 정리를 이용해 "빗변의 거리"를 구하는 방법으로 float d 값을 계산해 준다.

 

-  감사하게도 유니티에는 해당 벡터 값의 magnitude와 Distance를 바로 구하는 함수가 구현되어 있다.

 

-  세가지 값 모두 동일하지만 편의상 Vector3.Distance 함수를 가장 빈번하게 사용하게 된다.

 

 

 

 

 

 


 

 

 

 

게임에서 벡터가 필요한 이유는 ?

 

 

 

 

위치(Position)와 이동(Movement)

 

  • 벡터는 게임에서 캐릭터나 객체의 위치를 나타내는 데 사용한다.
  • 캐릭터의 이동은 현재 위치 벡터에 이동 벡터를 더함으로써 계산된다.

 

방향(Direction)

 

  • 게임에서 캐릭터나 객체가 향하는 방향을 나타내기 위해 벡터가 사용된다.
  • 캐릭터가 바라보는 방향이나 발사체의 경로 등을 계산할 수 있다.

 

충돌 처리(Collision Detection)

 

  • 벡터를 사용하여 객체 간의 거리 계산, 충돌 지점 확인, 충돌 후 반사 벡터 계산 등을 수행할 수 있다.
  • 충돌 이후 물리 엔진은 벡터를 사용하여 힘(Force)과 충돌 반응 등을 계산한다.

 

회전(Rotation)

 

  • 벡터와 행렬을 이용하여 객체의 회전을 계산할 수 있다.
  • 3D 게임에서는 쿼터니언을 사용하여 회전을 표현하기도 한다.

 

 

 

 

이외에도 수많은 상황에서 벡터가 필요하고 게임 엔진은 벡터를 이용해 우리의 기능 구현을 도와주고 있다 !

 

 

 

 

 

 

벡터의 정규화

 

 

  • 벡터의 정규화란 벡터의 방향을 유지하면서 크기를 1로 만드는 과정을 뜻한다.

 

  • 방향만 가진 형태의 벡터, 즉 정규화를 완료한 벡터는 "단위 벡터" 라고 부른다.

 

  • 벡터의 크기를 일정하게 유지하기 위해서는 벡터의 정규화가 필수적이다.

 

 

 

 

 

벡터를 활용해 오브젝트를 이동하는 예시

 

 

 

 

위의 알약 모양 오브젝트를 바둑판 모양 바닥을 클릭하면 해당 위치까지 이동하는 기능을 유니티로 구현해보자.

 

 

먼저 마우스 클릭 입력을 받아 해당 위치를 알아와야 하는 작업이 1차적으로 필요하고

 

알아온 위치를 바탕으로 해당 위치까지 이동하는 작업이 필요하다.

 

 

public class E04MoveObject : MonoBehaviour
{
    Vector3 targetPosition;

    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if(Physics.Raycast(ray, out RaycastHit hit))
            {
                if(hit.collider.gameObject.layer == LayerMask.NameToLayer("Plane"))
                {
                    targetPosition = hit.point;
                    Debug.Log(targetPosition);
                }
            }
        }

        Vector3 target = targetPosition - transform.position; // 목표 위치와 현재 위치를 실시간으로 빼줘서 얼마나 이동해야 할지 계산

        if (target.magnitude > 0.1f)
        {
            Vector3 normalizedTarget1 = target / Mathf.Sqrt(Mathf.Pow(target.x, 2) + Mathf.Pow(target.y, 2) + Mathf.Pow(target.z, 2)); // 벡터의 정규화
            //Vector3 normalizedTarget2 = target / target.magnitude;
            //Vector3 normalizedTarget3 = target.normalized;

            transform.Translate(normalizedTarget1 * Time.deltaTime * 5.0f);
        }
    }
}

 

 

 

마우스 좌클릭을 Update()란에서 입력 값으로 받아오고 해당 Ray 값을 targetPosition 이라는 벡터에 저장한다.

 

target은 실시간으로 targetPosition 나의 오브젝트 위치를 계산하여 이동해야 하는 거리를 갱신한다.

 

target, 즉 이동해야 하는 거리가 0.1f 정도가 남을때까지 이동하는데
(target.magnitude == 0 으로 하면 정확한 float 값을 일치시키는것이 어려움)

 

target 벡터를 해당 크기로 나누어줘서 벡터를 정규화 시켜준다.

 

 

이후 해당 방향으로 이동시키면 끝난다.

 

 

 

 

예상대로 잘 동작하는 모습이다.

 

 

 

정리

 

 

  • 벡터는 "크기"와 "방향"이다.
  • 게임 개발에서 벡터는 상당히 다양한 분야에서 활용된다.
  • 벡터의 덧셈과 뺄셈, 곱셈 등을 이용해 여러가지 값을 구할 수 있다.
  • 벡터의 정규화와 단위 벡터는 벡터의 크기를 일정하게 유지하기 위해서 꼭 필요하다.

 

 

 

 

 

 

그림 출처 :
https://mathinsight.org/vector_introduction

https://itch.io/blog/658632/16-bit-vector-normalization-finally-putting-that-math-major-to-work

728x90
반응형

'게임수학' 카테고리의 다른 글

게임수학 - 삼각함수  (0) 2024.07.15