벡터!!!
게임 수학에서 벡터는 매우 중요한 역할을 한다 주로.... 물리 엔진, 캐릭터 이동, 충돌 감지, 카메라 제어 등 다양한 분야에 사용된다고 한다
이 글에서는 벡터의 기본 개념과 게임 개발에서 벡터가 어떻게 활용되는지와 간단한 활용 예제를 만들어 보려고 한당
벡터
- 크기와 방향을 가진 물리량
- 관점마다 다르지만 컴퓨터 그래픽스에서는 위치, 방향, 크기를 표현
- 크기와 방향 개념이기 때문에 시작점과 끝점이 없지만 시작점을 원점으로 정하면 끝점이 존재함(위치 벡터)
벡터의 연산
- 덧셈: 걍 더하면 됨
덧셈을 하면 이렇게 평행사변형이 된다 그림을 그려보면 이해가 잘 될 듯
- 빼기: 걍 빼면 됨
공식은 생략하고 그림을 그려보면 b 벡터에서 a벡터로 향하는 벡터가 나오게 된다
하지만 벡터는 크기와 방향 개념이기 때문에 저 검은 두 화살표는 같은 벡터다
벡터의 길이
- 벡터가 나타내는 길이 또는 크기(Magnitude)를 의미하며 벡터가 공간에서 얼마나 멀리 뻗어 있는지를 나타낸다
- 벡터의 크기는 피타고라스의 공식으로 구할 수 있따
- 벡터의 길이를 1로 만드는 단위화(normalize)가 있는데 이건 순수 방향만 나타내고 싶을 때 사용
-> normalize 공식: 벡터를 벡터의 길이로 나누기
유니티에서는 벡터를 어떻게 활용하고 있을까?
- 이미 유니티에서는 위에 쓴 내용을 토대로 기능이 구현되어 있다
기본적으로 Vector들의 연산도 가능하고 길이 값을 반환해 주는 Magnitude함수, 단위화를 해주는 normalize() 함수가 이미 존재한다
먼저 유니티를 시작하면 가장 먼저 접하는 오브젝트의 Transform postion이다
두 벡터를 선형결합했을 때 두 스칼라로 얻을 수 있는 모든 벡터를 생각하면 평면 위 모든 경우에 다다를 수 있고 그럼 벡터는 화살표가 아닌 점의 개념으로 보게 되어 무한한 2차원 평면, 3차원 그 자체가 된다..... ㄷㄷㄷ
암튼 position이 벡터긴 하지만 점의 개념으로 보았고 저 좌표는 즉 벡터의 종점 좌표인 셈이다
이건 벡터를 방향 개념으로 본 듯한다
두 번째 벡터의 연산
간단하게 오브젝트로 공부해 본 것을 벡터 덧셈을 테스트해 봤다
유니티 개발하는 동안 이건 그냥 당연했고 신경 쓰지 않았던 부분인데 벡터를 공부하고 보니 좀 다르게 느껴졌다.....
세 번째는 벡터의 길이
순수 방향만을 나타내는 단위화를 테스트해보려고 한다
유니티의 Input.GetAxis를 사용하면 방향키에 따라 오브젝트의 방향을 구할 수 있따
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector3 direction = new Vector3(horizontal, 0, vertical);
transform.Translate(direction * moveSpeed * Time.deltaTime, Space.World);
각각 WASD를 누르면 위 그림과 같이 길이가 1인 벡터가 나오게 된다 저 값으로 오브젝트를 움직이게 된다
하지만 W D를 같이 눌러 대각선으로 가고 싶다면??
길이가 루트 2인 벡터가 나오게 된다 그렇게 되면 대각선으로 움직일 때 더 빨라지게 되는 문제가 생긴다
이 경우에 normalize를 사용하여 길이가 1인 벡터를 이용하게 되면 문제가 해결되게 된다
기존에 내장되어 있는 normalize함수 말고 직접 만들어 보자!!
private void Update()
{
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector3 direction = new Vector3(horizontal, 0, vertical);
Debug.Log(NormarlizedBy밤톨(direction));
}
Vector3 NormarlizedBy밤톨(Vector3 dir)
{
Vector3 result = Vector3.zero;
// 전에 만들어 놓은 피타고라스의 정리 함수
float magnitude = PythagoreanTheorem.GetDistance(Vector3.zero, dir);
if (magnitude > 0)
{
result = dir / magnitude;
}
return result;
}
결과
W D를 눌렀을 때 -> 0.71, 0, 0.71
길이가 1인 벡터가 나오게 된다~~ 성공~~
다음엔 벡터의 내적 외적을 공부해 보자