게임 심화편 프로토타입2
GCC 사관학교
안녕하세요
슈팅게임 제작 강의를 맡게 된 이영호입니다
이번 단원에서는
프로토타입 두 번째 내용을 학습하도록 하겠습니다
먼저 Vector를 이해하고 이를 이용해
등속운동 공식을 바탕으로 플레이어를 이동시켜 보겠습니다
그리고 해당 사용자 입력 처리에 따른 이동을 구현해 보도록 하겠습니다
Vector의 이해
자 그럼 벡터의 이해부터 알아보도록 하겠습니다
먼저 샘플 코드를 임의로 한번 만들어 볼게요
플레이어가 오른쪽으로 계속 이동하는
코드를 한번 만들어 보겠습니다
플레이어가 오른쪽으로 계속 이동하고 싶다
이 내용을 한번 작성해 보도록 할게요
transform
Translate
여기다가 Vector3.right * 5 * Time.deltaTime
이렇게 넣어보도록 하겠습니다
이렇게 하면 플레이어가 오른쪽으로 계속 이동하고 싶다는
내용을 넣은 거고요
이 한글 내용을 먼저 저희가 써봤잖아요
이 내용을 보면
얘가 Start가 아닌 Update에 있는 이유가 있죠
살아가는 동안 계속해서 뭔가를 하고 싶을 때
그때 이 문장 자체가
Start가 아닌 Update에 와야 되는 이유예요
이렇게 저장을 하고
이제 와서 플레이를 해 보도록 하겠습니다
플레이 버튼을 눌러보면
플레이어가 오른쪽으로 계속 이동하고 있죠
이 내용을 가능하게 하는 이 문장이 중요합니다
이걸 위해서 몇 가지 내용들을 알아 봐야 될 텐데요
벡터에 대한 내용을 알아보고
그다음에 이 문장 전체에 대해서도 알아보도록 하겠습니다
그러면 먼저 벡터라는 애는 어떻게 되어있는 거냐
일단 생김새를 보면 이런 식으로 생겼어요, 화살표로
이 화살표는, 이 몸통 부분 있잖아요?
이 몸통 부분, 꼬리 부분이라고 할게요
이 꼬리 부분과 머리 부분 이렇게 보도록 하겠습니다
이 부분을, 파란색으로 되어있는 부분을 크기라고 하고요
그리고 이 빨간색으로 되어있는 화살표 부분 있죠?
이것을 우리가 방향이라고 얘기합니다
그래서 이 벡터라는 애는 두 가지 성분을
함께 포함하고 있는 요소인데요
하나는 크기고요 하나는 방향입니다
이 두 가지를 함께 가지고 있는 애를
우리는 벡터라고 얘기를 해요
이 벡터는 우리가 물리적인 어떤
움직임을 표현하려고 할 때
굉장히 중요하게 사용되는 요소거든요
단순하게 어떤 역학 중심의 물체를 이동한다
이것뿐만 아니라
우리가 빛에서, 어떤 빛이 어떤 물체하고 와서 부딪히고
어떤 물체하고 부딪히고 다시 반사되는
이 모든 것들을 시뮬레이션 할 때
이 벡터라는 애를 결과적으로 많이 사용하게 되는데
당장 이 화면에서 보는 것처럼
빛의 방향을 뜻하는 이 화살표 자체가 다 뭐예요?
바로 벡터로 볼 수가 있습니다
그래서 여기에서 벡터에 대한 내용을 잘 이해해 두시면
실제로 이렇게 유니티를 이용해서
게임을 만드는 이 과정에서
가장 핵심적인 부분을 잘 이해하게 되실 거예요
그러면 먼저 벡터의 여러 가지 특징들이 있는데요
벡터는 기본적으로 화살표로 표현하는데
얘는 사칙연산이 가능합니다
사칙연산이라고 하면 우리가 아는 게
더하기, 빼기, 곱하기, 나누기가 있죠
그렇죠? 나누기 이렇게 있는데
벡터에서는 이 나누기하고 곱하기
곱하기만 사용을 하는데요
곱하기는 두 가지로 나눠져요
하나는 Dot Product라고 해서
이렇게 점으로 하는 연산을 뜻하고요
그다음에 Cross Product라고 해서
이 형태로 사용하는 두 가지의 곱하기가 있습니다
얘는 점이니까 Dot Product라고 하고요
얘는 이렇게 곱하기 x 모양으로 했죠
그래서 얘를 Cross Product라고 해요
얘는 한국말로 내적 이렇게 얘기하고요
얘는 외적 이렇게 얘기합니다
여기에서 우리가 주의깊게 봐야 될 것들은
더하기, 빼기 이 부분을 먼저 깊게 알아 두시고요
이것들을 우리가 작업하기 위해서
이 두 가지가 되게 중요합니다
그리고 내적과 외적은 굉장히
여러가지 용도로써 또 사용이 돼요
이 내적은 두 가지의 벡터를 가지고 연산을
곱하기 연산, 내적 연산을 하면
하나의 숫자 값이 나오게 됩니다
우리가 벡터를 크기와 방향으로 이루어져 있다고 했는데
이 크기 값을 우리는
스칼라, 혹은 스캘러 이렇게 발음하죠
이 Scalar 값이라고 합니다
이 두 개의 내적, 즉 크기와 방향으로 가지고 있는
얘를, 두 개의 벡터를 내적하면
하나의 스칼라 값이 나오게 되는 게 바로 내적이고요
그다음에 이 Cross Product, 외적은
두 개의 벡터를 외적을 하면
이 두 개의 벡터의 직각인
이런 벡터가 하나 튀어나오게 돼요
이걸 가지고 우리는 외적이라고 합니다
두 개의 벡터는 각각의 목적에 따라서
굉장히 중요한 역할들로 사용이 되는데
지금 이번에 저희가 알아볼 건
더하기하고 빼기를 알아보도록 하겠습니다
그러면 더하기는 어떤 용도로 사용이 되느냐가 중요하겠죠
두 개의 벡터가 존재한다고 볼게요
자 보시겠습니다
여기에 A의 벡터가 있고요
그다음에 여기에 b의 벡터가 있습니다
A의 벡터는 단순하게 여기에다가만 놓을 수 있는게 아니라
이 위에도 놓을 수 있어요
이 벡터라는 애는 크기와 방향이라고 했죠?
즉, 여기에는 위치가 포함된 형태가 아니에요
바람이, 이 A를 바람이라고 볼게요
바람이 이렇게 불고 있는 거예요 지금
이렇게 바람이 이렇게 불고 있는 거예요
바람이 딱 이 지점에서
이 지점에서 이렇게 불진 않죠
여러분들 창문을 열었을 때 바람은 어떻게 불어요?
그냥 이렇게 들어오죠 바람이
바람이 이렇게 들어와요
제가 있으면 바람이 이렇게 들어오는 거예요
그래서 얘 자체는 위치하고는 상관이 없어요
그래서 여기다가 놓든 여기다 놓든 바람이니까
이렇게 부는 거예요 바람이 분다고요
그래서 A의 위치를
A의 이 벡터를 여기에다가 놔도 상관없겠죠?
그러면 우리가 키보드의 오른쪽 키를 누르고
그다음에 위 화살표 키를 눌렀다고 칠게요
그러면 비행기가 두 개를 동시에 눌렀을 때는
어떻게 가야 될까요?
마지막 그림에서처럼
이렇게 대각선으로 가야 된다는 것들을 알 수 있겠죠?
즉, 두 벡터의 더하기는 이렇게 끝점을 이었을 때
두 개의 마지막 점에 대해 있는
여기로 향하는 벡터를 구할 수가 있습니다
벡터의 더하기는 이렇게 돼요
그래서 우리가 이 벡터의 더하기는
모든 힘의 합을 뜻합니다
예를 들어 볼까요?
우리가 공을 하나 던져 볼게요
이렇게 공을 던져 볼게요
이렇게 공을 슝 던져보도록 하겠습니다
그러면 이 공은 실제로 무한대로
이 방향으로 계속해서 날아갈까요?
그래서 지구를 뚫고도 날아가나요? 어떻게 날아가죠?
실제로?
이렇게 포물선을 그리면서 날아가게 되겠죠?
그렇죠? 결국에는 바닥에 떨어질 거 아니에요
일반적인 경우라면 날아가서 떨어지게 될 거예요
이 이유가 뭐죠?
바로 중력이 작용하니까요
중력은 어떻게 작용하죠?
이렇게 아래쪽으로
즉, 두 개의 화살표를 더해 보면
이렇게 되는 것을 볼 수가 있어요
바로 이렇게 되는 게 아니라, 얘는 어때요?
중력이 점차 나의 힘에 영향을 줘서, 어떻게 돼요?
얘가 뚝뚝뚝뚝뚝뚝 가면서 이렇게
포물선 운동을 하게 되는 경우죠
그래서 벡터는 더하기를 이용했을 때
모든 힘의 합을 표현할 수가 있어요
만약에 바람이 역으로 쓱 불었어요 이렇게
그리고 중력도 작용하고 있어요
얘네들을 다 더하면 이 바람의 힘이 굉장히 쎘을 때
공은 어떻게 날아갈 것 같아요?
이렇게 슝 날아가다가 바람 때문에 다시
이렇게 해서 다시 돌아가는 이런 느낌
그렇죠? 이렇게 들어가는 느낌으로 연출이 될 수 있겠죠
그러니까 바람은 이쪽 힘이고
우리가 던진 힘은 이쪽이고
아래로 떨어지는 중력의 힘
얘네들을 다 더했을 때 최종 물체의 위치가 정해집니다
바로 이 벡터가 정해지게 되는 거예요
더하기는 이런 목적으로 사용이 된다는 거
알아두시면 좋을 것 같고요
대표적으로 야구 게임, 골프 이런 것들이 있잖아요
그 다음 당구, 이 모든 것들은
이 벡터에 더하기를 사용한다고 보시면 되겠어요
빼기는 그러면 어떻게 사용을 할까요?
빼기는, 결국에는 빼기도 더하기에 해당이 되겠죠?
빼기도 A가 있으면 이렇게 해서 할 수가 있는 거잖아요
그러니까 빼기도 결국엔 더하기가 되지만
우리가 사용 목적에 따라서
좀 달라진다고 볼 수가 있겠어요
A벡터가 이렇게 있고요, B벡터가 있어요
A를 빼 볼게요
그러면 신기하게 어떻게 되어있어요?
A에다가 빼기를 붙이면 벡터의 방향이 뒤집혀지죠
즉 여기서 알 수 있는 것
음수, 마이너스가 곱해지잖아요?
-1이 곱해지면 어떻게 되느냐?
바로 벡터의 방향을 바꿀 수 있다는 것
아실 수 있겠죠?
그러면 A의 벡터가 이쪽을 가리키고 있고
B의 벡터가 이렇게 가리키고 있어요
그러면 앞에, 위에 더하기에서처럼
어떻게 될 수 있어요? 벡터는 마지막에?
최종 벡터는 이렇게 될 수 있죠
즉 B - A는 어떻게 구해지느냐?
이렇게 구해진다는 거예요
이런 거는 그러면 어떻게 알 수 있어요?
즉 A가 마치 B로 가고 싶은 거죠
그래서 벡터의 빼기는 이렇게 볼 수가 있습니다
어떤 식으로 활용이 되느냐?
여기에 내가 있고요, 이쪽에 타겟이 있습니다
그래서 내가 타겟 방향으로 이렇게 가고 싶어요
타겟 방향으로 이렇게 가고 싶어요
그럼 이 벡터를 우리가 구하려는 게 우리의 목적이에요
이때 어떻게 하냐면, 내가 어디로 가고 싶다고요?
타겟 방향으로 가고 싶다고요
이 벡터를 우리가 방향이라고 놓을게요
그러면 이 Direction, 이 벡터는 어떻게 구하냐면
바로 Target - Me
이렇게 해서 내가 타겟으로 가고 싶을 때는
이렇게 구하시면 됩니다
Target - Me 하면
나에서 타겟으로 향하는, 목적지로 향하는
벡터를 구할 수 있다는 얘기에요
됐죠? 이렇게 구할 수가 있습니다
여기서 한 가지만 더 알아볼까요?
얘를 제가 그래프로 한번 그려볼게요
자 이렇게 이렇게
직교좌표계로 이렇게 놓도록 하겠습니다
여기 X축이 있죠? 여기 Y축이 있습니다
그렇죠? 이렇게 되어 있어요
보기 편하게 이쪽으로 좀 옮겨 놓을까요?
그러면, 보시면
내가 여기에 있고, 타겟이 이 지점에 있어요
두 개를 위치를 이렇게 보시면 어때요?
여기에서 이만큼까지, 여기까지
x1이라고 놓도록 하죠
여기는 x고, 여기는 x1이라고 놓을게요
그러면 이만큼은
이 지점, 여기는 Y1이라고 놓도록 하죠
즉 이 벡터를 나한테 만약에 더해줬다고 칠게요
나의 위치가 만약 이 지점이라면
나의 위치에다가 이 벡터를 더해주면
나는 최종적으로 어느 위치에 가있다고요?
타겟 위치에 가있다고
그럼 내가 여기 서있는데
이 서 있는 캐릭터가 저쪽으로 이동했을 때
이 벡터를 그냥 더해버리면
얘는 순간이동처럼 움직이게 되겠죠?
이것은 저희가 원하는 형태의 움직임이 아닐 거예요
저희는 어떻게 하고 싶어요?
이렇게 내가 가진 속도대로 이렇게 가고 싶은 거예요
그쪽 방향으로
그러면 이 벡터가
크기와 방향으로 이루어져 있다고 말씀드렸잖아요
그러면 이 크기 부분이 필요한 게 아니라
저는 단순하게 이쪽 방향만 있으면
이 방향으로 이 캐릭터를
단순하게 이동시키기만 할 거잖아요 이 방향으로
그러면, 자 보세요
크기와 방향으로 이루어져 있다고 했죠
제가 여기에 곱하기를 써놨습니다
그때 나는 방향만 필요해요
그래서 나의 이동 속도가 있을 거 아니에요?
나의 속도를 여기다 곱해 볼게요
그랬을 때 이 벡터의 크기가
단순하게 어떻게? 이렇게 되는 게 아니라
이렇게 됐으면 좋겠죠
그래서 나의 속도로 이만큼씩 이동했으면 좋겠는 거예요
그러면 우리가 벡터의 빼기를 이용해서 나온 이 벡터가
몇이 되면 나의 속도
여기 나예요
나의 속도와 방향만 남게 될까요?
이 크기가 몇이 되면?
바로 1이면 되겠죠
그래서 이 Target - Me에서 나온 얘네를
이 벡터의 크기를, 이 디렉션의 크기를
1로 만들어주는 이 행위를 우리는
벡터의 정규화라고 하고요
정규화라고 하고, 영어로는 Normalize라고 합니다
이렇게 얘기하는 거예요
얘는 바로 내가 벡터의 빼기를 이용해서 구한
이 벡터를 가지고
나의 속도로 이동하고 싶을 때 하는 행동
이때 벡터의 정규화 이렇게 사용합니다
그러면 여러분들이 게임을 만들 거예요
MMORPG 게임 같은 걸 한다고 치죠
마우스 포인터로 이쪽을 클릭했습니다
이렇게 이쪽을 클릭했어요
그럼 캐릭터가 이쪽에 서 있다가
이 방향으로 이동해야겠죠
그러면 어떻게 하면 돼요?
나의 위치, 마우스가 클릭한 타겟의 위치가 구해지겠죠
바로 Target - Me 하면 이 벡터가 구해지게 될 거예요
그럼 내가 어떻게? 이 방향으로 이동하겠죠
MMORPG 같은 거에서
그러면 이 벡터를 그대로 더해주는 게 아니라
어떻게 된다고요? 얘를 Normalize해서
이런 벡터로 만들어 줘야 돼요
즉 이렇게 정규화된 벡터로 만들어 줘서
그 방향으로 이동을 하면
나의 속도로 이동할 수 있게 됩니다
이걸 Normalize라고 하는 거예요
그래서 벡터는 크게
더하기, 빼기, 내적, 외적이 있다고 했는데
이번에 저희가 알아본 건 더하기하고
빼기까지만 알아봤습니다
자 그러면 앞에서 했었던 이 문장에서
플레이어가 오른쪽으로 가는 이 부분에서
여기 Right라고 되어 있는 부분 있잖아요?
바로 얘는 벡터니까
벡터의 오른쪽이라는 방향을 갖고 있는 거예요
크기는 몇일까요? 1인 거예요
뒤에 있는 5는 뭘까요?
바로 나의 이동 속도가 되겠죠
뒤에 있는 애는, 뒤에서 다시 한번 얘기하겠지만
등속운동에서 사용하게 되는 시간일 뿐이에요
등속운동에서 사용하는 시간
그러면 어때요?
이만큼이 바로 내가 만들어낸 벡터라는 얘기겠죠
그리고 뒤에 있는 것은 시간이 곱해진 거예요
등속운동 공식 이해 및 플레이어 이동 제작
그러면 다음으로 등속운동 공식에 대해서
한번 알아보도록 하겠습니다
보시면 여기에 앞단에 먼저
뉴턴의 운동역학에 대한 내용이에요
이 첫번째 부분이 P = P0 + vt
v = v0 + at
세번째가 F = ma
이렇게 되어있죠
마지막에 있는 F = ma
여러분들의 DNA에 아마 박혀 있을 거예요
F는? 하면 어떻게?
여러분들이 어디에 쓰이는지 모르겠지만, ma?
이렇게 나오게 되는 부분이 바로 F = ma 부분이에요
그래서 어떤 물체가 역학적으로
운동역학에 의해서 이동하거나 이렇게 될 때
이 세가지의 공식들을 이용하는 거예요
그래서 유니티에 탑재되어 있는 내부 안에서의 물리엔진도
바로 이 부분의 공식을 이용해서
물체들이 이동하는 부분이 구현되어 있습니다
이 중에서 첫번째가 바로 등속운동 공식이고요
여기에 사람이 하나 있다고 칠게요
뒤에서 여러분들이 밀었어요
쿵 하고 밀었습니다, 푹 하고 밀었어요
그러면 이때 이 사람은 어떻게 될까요?
이 사람이 여기 있을 때 뒤에서 탕 밀으면
얘는 이쪽으로 이렇게 밀려나겠죠
뭐 당연한 거죠
이때 이렇게 물체가 이동하는 이 형태가
바로 이 공식에 의해서 만들어지는 거예요
먼저 이 사람이 가만히 있었던 현재의 위치를
P0이라고 넣도록 할게요
현재 위치에요
포지션
그다음에 얘가 미래의 나의 위치입니다
얘를 P라고 놓도록 할게요
그다음에 이 가운데
사용자가 뒤에서 밀었을 때 발생한 이 방향이 있죠
얘를 화살표가 나왔죠
이걸 우리가 뭐라고 한다고요?
벡터라고 한다고요
이거는 속도, Velocity의 V라고 넣도록 할게요
Velocity, V
얘는 벡터
그러면 이 사람이 순간 이동하는 게 아니라
시간에 따라서 점점 이동을 해서 이렇게 가겠죠
그래서 뒤에 T가 붙어 있어요
그래서 이들은 시간에 따라서 이동하게 되어 있어요
그러면 이거를 다시 한번 보도록 할게요
뒤에서 쿵 밀었습니다
밀었죠?
얘를 밀면 힘이 작용을 합니다
힘이 작용을 해요
앞에 있는 얘는 등속 운동이라고 하고요
뒤에 있는 얘는 등가속 운동이라고 하고
밑에 있는 거
마지막으로 이렇게 힘은 F = ma
이거까지 들어가는 거예요
자 여기에 있는 A가 뭐냐면
이 부위는 현재 위치에 영향을 주게 되는
바로 속도고요
Velocity, 속도고요
a는 속도에 영향을 주는 가속도라고 해요
됐죠?
여기 있는 m은 질량이에요
물체의 질량
즉 질량을 여기서 1이라고 넣도록 합시다
그러면 F는 곧 뭐가 되죠?
a가 되죠?
뒤에서 제가 힘을 줘서 밀었어요
그러면 뭐가 발생해요?
a가 만들어지죠
a가 만들어져요
a는 어디에다 영향을 주죠?
현재 속도에 더해져서
v0도 현재 속도예요
v0, 현재 속도에 영향을 줘서 새로운 속도를 만들어내죠
새로운 속도가 만들어지고
자 v가 변했어요
이 부위가 만들어졌죠
그러면 v는 어디에 영향을 주죠 보니까?
현재의 위치에 더해져서
미래의 위치에 변화를 주네요
그래서 뒤에서 이렇게 밀면 힘이 생기고요
힘은 곧 가속도가 만들어진다는 얘기에요
그러면 이 부위에 영향을 줘서 새로운 v가 만들어지고요
그러면 플레이어 P0가 P로 이동하게 되는
변하게 되는 이 구조를 만들어내는 게
바로 등속운동 공식이라고 볼 수 있겠습니다
그러면 우리가 만들어내는 모든 게임
혹은 어떤 실감 콘텐츠
이런 모든 것들은 다 뭐예요?
가상 공간에서 일어나는 거죠
가상 공간에서 우리가 시뮬레이션 하는 거예요
그렇게 하기 위해서는 바로 이 역학
운동역학에 대한 부분을 이해할 수밖에 없어요, 왜?
게임도 결국에는 이 역학 쪽을
현실하고 똑같이, 비슷하게 만들어내는 거잖아요
그래서 이 운동역학을 우리가 가져다가
게임에서 사용을 해야 됩니다
거기에서 중요한 게 앞에서 배운
바로 벡터라는 부분이에요
그러면 여기서 조금 더 내용을 보면
여기에서 보이는 P0은
어느 플레이어의 단순한 위치일 뿐입니다
위치고요
P도 위치일 뿐이죠
여기에서 t는 스칼라 값, 시간이에요
여기에서 v는 바로 이 화살표를 뜻하죠
그래서 머리에다가 이렇게
벡터를 그려주는 거예요, 화살표를 이렇게
얘는 뭐라고요?
화살표, 벡터라는 표시에요
a도 바로 가속도, 중력 가속도라고 하죠
아래로 화살표가 작용하는
그래서 얘도 화살표
F도 화살표, a도 화살표
여기 있는 m은 질량이라서 숫자 1뿐이에요
스칼라 값
이렇게 표시할 수가 있겠습니다
이게 등속 운동 공식이에요
이걸 이용해서 우리 플레이어의 이동이
만들어지게 되겠습니다
그러면 이것을 이용해서
플레이어의 이동을 제작해 보도록 할게요
코드에서 보시면
이 부분 자체가
이만큼, 이 부분에 있는 이만큼이
바로 v가 되는 거예요
왜? P는 뭐라고요?
P0 + vt 라고요
여기에서 얘가 이렇게 벡터
그러면 v는 크기와 방향을 가지고 있는 벡터죠
그래서 V는 방향 × 크기 해서 v가 만들어진 거예요
여기 뒤에 있는 t는 바로 deltaTime이라고 얘기하는 거예요
앞에서 이 tranform.Translate
얘는 내부적으로 이 공식을 구현해 주는 게
바로 이 트랜슬레이트의 내부 함수의 기능이겠죠
그럼 여기 뒤에 있는 이 deltaTime은
바로 t를 뜻한다고 되어있는데
그럼 이 델타타임은 어떤 시간인가
를 잠깐 알아보도록 하겠습니다
델타타임에 대해서 조금 더 알아보도록 할게요
보시면 이 앞의 것과
그다음에 아래에 있는 얘네를 보면
얘는 새로운 PC 입니다
새로운 컴퓨터를 열어보면서 새로 산 거예요
아주 최신 그래픽 사양과
메모리와 하드디스크 이 모든 것들을
빵빵하게 해서 샀어요
여기 밑에 있는 거는
옛날 한 5년 정도 된 PC 라고 볼 수가 있습니다
사용이 그때는 나쁘지 않았었는데
5년 정도 지나니까 아주 느려졌어요
위에 있는 이 점선 이 그래프 있잖아요
이 그래프는 뭐냐면
이거는 새로운 PC가 1초 동안에 수행할 수 있는
횟수인 거예요
그래서 여기가 1초라고 보고요
새로운 PC는 1초 동안에 어떻게 수행을 할 수 있느냐
이 물체가 이동한다고 봤을 때
얘는 총 하나, 둘, 셋, 네 번을 이동할 수가 있어요
4칸을 수행할 수 있다는 거예요, 1초 동안에
밑에는 두 번을 수행할 수가 있죠
이해 되셨나요?
이렇게 두 번을 수행할 수 있고
이때 이 캐릭터가 한 번 움직일 때마다
1m씩 이동이 가능하다고 보시죠
그러면 위에 있는 새로운 PC는
네 번을 이동하니까
한 번 이동할 때마다 1m
즉 1초 후에는 얘는 첫 번째 새로운 PC에서는
몇 m를 이동할 수 있죠?
4m, 그렇죠?
그럼 이 아래에 있는 옛날 5년 된 PC는
두 번을 움직일 수 있죠
얘도 마찬가지로 한 번 움직일 때마다
똑같이 1m 움직일 수 있는 거예요
그러면 얘는 총 1초 후에는 2m 움직이겠네요
이렇게 되면 어때요?
얘는 새로운 PC니까 1초에 4m씩 이동할 수 있고
얘는 2m씩 이동할 수 있고
여러분들이 게임을 할 때
위에 있는 PC는 정말 빠르게 이동해서
움직일 수 있어요
즉 5년 된 PC와 새로운 PC가 게임을 하면
첫 번째, 새로운 PC가 무조건 이기게 되는 구조죠
이러면 너무 불공평해서
사용자들이 게임을 안 하게 될 거예요
우수수 사용자들이 빠져나가는 소리가 들리시나요
이렇게 하면 공평하지 않기 때문에
룰이 너무 불공정해요
그래서 어떻게 하면 이들을 1초 후에
같은 위치에 도착할 수 있게끔 맞춰 줄까
이게 굉장히 중요한 포인트라고 볼 수 있겠습니다
그러면 4m, 2m가 아니라
어떻게 1초 후에 같은 속도로 이동을 해서
최종 같은 목적지에 도착하게 할까
이 부분이 바로 Delta Time의 핵심이에요
이 앞에 Delta라고 붙은 거 있죠
이 델타는 변위한 거예요, 변한 거예요
변위 시간이란 얘기에요
뭐가 변한 거냐? 시간이 변했다는 얘기죠
어떻게 변한 거냐
바로 여기에서 첫째 프레임에서
이 프레임이 끝나는 동안
이때 델타, 얼마큼 걸렸니?
이게 바로 델타타임이라고 보시면 되겠어요
보시면 전체가 1초라고 보면
총 4번을 수행할 때
각각의 프레임 간, 이 한 칸, 한 칸들을
우리가 프레임이라고 얘기합니다
여러분들이 어렸을 때 이런 장난 해보셨나요?
책이 이렇게 있어요
책이 있으면 여기다가 그림을 하나 그리는 거예요
뒤에다가도 어떻게?
뒤에다가도 이런 그림을 그리는 거예요
달리는 그림, 그래놓고
책들을 매 페이지에 이렇게 쭈르륵 그려 놓은 다음에
책을 저희가 빠르게 샥 넘겨볼게요
타르륵 넘겨보면 어때요?
마치 얘가 달리는 것 같은 애니메이션을
만들어 낼 수 있겠죠
이런 장난들 한번 해보셨을 거예요
이 각각의 한 장, 한 장들 있죠
이 한 장, 한 장을 우리가 뭐라고 부르냐
바로 프레임이라고 합니다
어디에서는 틱이라고도 얘기하고요
유니티에서 바로 이 한 장, 한 장들을 프레임이라고 해요
보통 애니메이션 분야나 영화 분야에서
부드럽게 우리가 이것들을 볼 수 있게 하기 위해서
이 몇 프레임을, 1초에 몇 프레임을 제작을 하냐면
이렇게 한 장, 한 장 그려 놓는 거요
이것들을 24 프레임 정도 제작을 합니다, 초당
그래서 얘를 초당 프레임 레이트라고 해서
frame per second라고 해서 fps라고 얘기해요
first person shooting이 아닙니다
그렇죠 frame per second라서
24 프레임이 초당 만들어지는 거예요
이것들은 보통 우리가 애니메이션 분야들 있죠
여러분들이 극장에서 영화 볼 때 애니메이션 영화들은
보통 24 프레임 정도 사용하게 되는 거예요
그럼 게임에서는
보통 30 프레임에서 60 프레임 이 정도 사용하고요
VR 같은 형태의 콘텐츠들은
모바일에서는 최소 60 프레임 이상이고요
PC에서는 90 프레임 이상 사용합니다, PC에서는
왜? 사용자들이 고개를 확확 돌리거나 눈을 돌렸을 때
어지럼증을 느끼지 않게 하기 위해서
이 정도 초당 프레임 레이트
fps를 사용하게 되는 거예요
자 이때 이 deltaTime이 굉장히 중요하게 작동을 합니다
얘가 얼만큼 짧게 걸리느냐가
초당 프레임 레이트를 잡아내는 데 도움이 되겠죠
그렇다면 여기에서 델타타임의 활용도는
등속운동 공식에서 어떻게 사용되느냐
보시면 얘는 1m씩 이동을 할 수 있죠
근데 각각의 이 구간에 걸린 시간은 0.25초
전체 1초니까 4분의 1로 나누면 0.25초가 되죠
그래서 우리가 이동할 때 걸리는 거리는
스페이스 S라고 놓을까요 그냥? S라고 놓고요
그다음에 얘를 거리에서, 시간이니까 델타타임
× D라고 놓도록 할게요
이랬을 때 최종 이 위치가 나오는 거예요
그러면, S × 거리 × 시간이 있었죠
거리 × 시간 t, 이 두 가지를 했을 때 볼까요?
1m 이동합니다
시간, 델타타임을 곱해 볼게요
그럼 몇이 나와요? 0.25초
그러면 값이 몇이죠?
0.25m 이동한 게 최종 이동 거리죠
즉, 이 구간을 이동할 때 몇 m 이동했다고요?
0.25m
이 뒤에도 0.25m, 0.25m, 0.25m
다 더하면 최종 얘는 1m 이동하게 되죠
밑에도 마찬가지죠, 얘는 느린 핏이지만
얘가 구간당 0.5초나 델타타임에 걸린대요
이때는 1m 이동하는데 0.5초가 걸렸는데
두 개를 곱해보면 이 구간을 이동하면 몇 m 이동하죠?
0.5m, 얘도 0.5m
두 가지를 더하면 얘는 몇 m 이동했어요? 1m
즉, 아까는 얘는 4m, 얘는 2m였는데
두 개가 같아 졌죠
그래서 델타타임은 이렇게 사용이 되는 거예요
그래서 등속운동 공식에서도
P = P0 + vt 이렇게 해서 만들어졌지만
P = P0 + vt, 이때 뒤에 있는 t가 바로
그 이동한 순간 시간이에요
그 시간 때문에 코드에서도 deltaTime을 곱해줬지만
얘는 반드시 동기화 처리를 위해서
Time.deltaTime은 반드시 곱해 주셔야 돼요
얘는 단순하게 이동해서만 사용되는 건 아니겠죠?
여러분들이 회전을 한 형태를 한번 보도록 할게요
캐릭터가 하나 여기 있고요
이렇게 둘이 이렇게 있다고 칠게요
각자 이쪽을 바라보고 있습니다
여기에 뿅망치가 하나 있다고 볼게요
뿅망치가 이렇게 하나, 이렇게 있습니다
둘 다 시작!하면 회전을 싹 하는 거예요
회전을 싹 해서 얘를 망치를 잡아서 때리는 거예요
얘는 새로운 PC, 얘는 옛날 PC
얘가 더 빨리 회전할 수 있겠죠?
슉! 회전해서 뿅망치를 잡아서 꽝! 때리면 어때요?
무조건 새로운 PC가 이기겠죠?
그래서 회전을 처리할 때도 반드시
deltaTime을 곱해 주셔야 돼요
자, 이번에는 이런 경우를 한번 볼까요?
여기다가 알약을 하나 이렇게 놓을게요
알약을 하나 이렇게 놓도록 하겠습니다
시작!하면 서로 이 알약을 하나씩 먹을 수 있어요
하나씩 먹을 수 있어요, 시작!하면
시작!했을 때 얘도 먹을 수 있고 얘도 먹을 수 있어요
그때 얘는 확대를 하는 알약이에요
얘는 새로운 PC, New PC고요, 얘는 Old PC예요
얘는 이거 먹고 확대를 할 건데 어때요?
빠르게 확대가 되죠?
1초에 4번이고 얘는 2번 확대할 수 있으니까
얘는 4번 확대할 거예요
그래서 얘는 어떻게? 붕붕붕!
그래서 이만큼 커진 다음에 발로 밟아서 꽝!
그럼 얘가 무조건 이기는 게임이겠죠?
즉, 회전할 때도 반드시 뭐를 곱해줘야 돼요?
deltaTime을 곱해 줘야 됩니다
즉, 이 transform 컴포넌트에서 사용하는
포지션, 로테이션, 그다음에 스케일
이 세 가지 값들을 변경하려고 할 때
반드시 deltaTime을 곱해 주셔야
동기화 처리를 할 수가 있겠습니다
이렇게 하면 우리가 델타타임까지 알아봤습니다
이어서 이제 사용자 이동 코드로
이 transform.Translate를
우리가 방금 배워놓은
등속운동 공식으로 바꿔보도록 할게요
유니티에서 제공해주는 이게 아니라
등속운동 공식으로 직접 물리작업을 해서
역학을 구현해 보도록 하겠습니다
이동 공식은 어떻게 된다고요?
P = P0 + vt 이렇게 된다고요
그럼 우리가 필요한 건 먼저 P0이 필요하겠네요
P0는 바로 플레이어의 현재 위치가 될 거예요
그래서 먼저 P0을 만들어 볼까요?
Vector3, 얘는 앞에 자료형이고요
유니티에서 제공하는 x, y, z
세 가지 요소들을 가지고 사용할 수 있게 하는 거예요
그래서 뒤에 3이 붙었죠?
2D에서는 Vector2
숫자가 하나일 때는? 그냥 float 사용하는 거예요
저희는 3D라서 Vector3 이렇게 놓도록 하겠습니다
P0로 하고 놓고요
얘는 현재 플레이어의 위치니까
이 PlayerMove가 사용하고 있는
게임 오브젝트가 있죠
이 플레이어의 위치는 누가 갖고 있어요?
transform이 갖고 있죠
얘 포지션 값을 가져오면 바로
얘의 현재 위치 값을 가져올 수가 있어요
어떻게 쓰느냐? 이렇게 쓰시면 됩니다
transform.position
이렇게 쓰면 바로 P0가 만들어져요
바로 현재 나의 위치를 P0에 담는 거죠
그다음에 있는거 vt 이게 필요하죠?
그래서 Vector3에 vt를 해보면
v는 어떻게 된다고요? 바로 이만큼이 v가 되겠죠
이만큼이 v예요
이 뒤에 있는 얘는 방향이고 얘는 크기
그래서 크기 × 방향에서 이만큼이 v죠
그다음에 t는 deltaTime이죠
그래서 얘까지 뒤에다 곱해주면 이게 vt가 되는 거예요
그럼 마지막 P = P0 + vt를 만들어 보죠
P = P0 + vt
이렇게 되는 거예요 그러면 이 공식대로 최종 만들어졌죠
이렇게 값을 구했으니까
최종 현재 나의 위치에다가 갱신이 돼야 될 거예요
그래서 transform.position
나의 현재 위치에다가
뭐를 넣어 주면 돼요? P를 넣어주면
이게 값이 갱신이 되겠죠
이 부분은 이제 필요가 없으니까 지워주시면 되겠습니다
이렇게 하면 현재 플레이어의 위치를 바꾸게 되는
등속운동 공식을 이용해서 만들어내는 거예요
똑같이 바뀌어졌는지 한번 볼까요?
플레이 버튼을 눌러보면 사용자는 오른쪽으로 계속 이동하죠
이렇게 됐습니다
사용자 입력에 따른 이동 구현
그러면 이번에는 사용자 입력에 따른 이동을
구현해 보도록 할게요
사용자 입력은 사용자의 입력에 따라서
방향을 구할 수 있는 이것을 만들어내죠
사용자의 방향을 구할 수 있게 해줘요
여기서의 방향은 뭐죠?
이 부분이 사용자의 방향일 거예요
특히나 얘는 크기니까
이 부분이 방향으로 한정될 수 있어요
여기에서 저희가 조금 더 알아봐야 될 부분들
Vector3.right는
결과적으로 이 Vector3라는 부분은
x, y, z 이 3가지 성분을 가지고
방향을 만들어낸다는 거예요
유니티에서는 x가 오른쪽을 뜻하고요
y는 위를 뜻합니다, z는 바로 앞을 뜻해요
영어로 하면
요거 x 방향은 right 라고 할 수 있고요
얘는 up이라고 할 수 있고
얘는 forward 라고 합니다
forward 이렇게 됐을 때
x, y, z에 각각의 값이 어떻게 들어가냐
Vector3.right는 이 3가지 성분의 값이 들어가야 돼요
즉 x가 오른쪽이니까 얘한테 값이 1 들어가고요
y는 0, z 도 0 이렇게 들어가게 되는 거예요
값이 없어야지 오른쪽 방향으로 갈 테니까
얘의 크기는 1 입니다
크기는 어떻게 구하냐면요 이렇게 구해요
√(x^2 + y^2 + z^2) 이런 식으로 구하게 되는 거예요
얘가 1이니까 나머지 0이고, 루트 1은 1이죠
그러니까 크기는 1이 되는 거예요
이렇게 됩니다 그러면 여러분들
right 말고 up도 있겠네요 up도 있을 거예요
up은 그럼 어떻게 될까요?
이 형태로라면 y 축에만 값이 들어가면 되는 것 같아요
즉 x에는 0이고 y에는 1
forward일 땐?
y에 0이고 z에는 1 이렇게 되겠죠
아까 방향이 바뀔 때는 무엇을 곱하면 된다고요?
-1를 곱하면 벡터가 뒤집어진다고 얘기했어요
즉 그래서 만약에 뒤로 가겠다고 하면
벡터의 뒤로 가겠다고 하면 얘는 앞이죠
-1를 곱해 주시면 돼요
왼쪽은 x에 -1를 곱해 주면 되겠죠
× -1을 해주시면 된다는 얘기에요
이렇게 각 성분별로 곱해지니까 이렇게
0 × -1은 0이잖아요
그래서 아래로 가는 것도 이렇게 하시면 되겠습니다
그래서 × -1을 하면 벡터가 뒤집힌다
이 내용을 알아두시면 되겠어요
그러면 사용자의 입력을 받아서
플레이어가 상하좌우로 이동하게 하는 내용을
한번 구현을 해보도록 할게요
그러면 먼저 방향을 여기다가 만들어내기 위해서
사용자의 입력을 한번 받아 봅시다
사용자의 입력을 받아서 방향을 만들고 싶다
그럼 사용자의 입력을 어떻게 받냐면
Input이라는 클래스를 이용해서 사용자의 입력을 받아요
그러면 클래스 1을 한번 머릿속에 그려보세요
그럼 . 하면 어떻게 된다고요?
속성으로 기능에 들어가는 거죠
우린 여기에서 기능에 들어갈 거예요
GetAxis라는 기능에 들어갈 겁니다
GetAxis 하면 사용자의
계속 누르고 있는 입력들을 받아올 수 있어요
여기에 우리는 좌우 입력인
Horizontal 입력을 받아오도록 하겠습니다
얘를 사용자가 아무 키도 누르고 있지 않으면
이 GetAxis라는 애는 값을 0을 넘겨줘요
근데 A키나 혹은 화살표 왼쪽 키를 누르면
얘가 -1 값을 넘겨주고요
점차 0부터 -0.1, -0.2 이렇게 주르륵 바뀌어서
-1까지의 값을 넘겨주게 돼요
오른쪽 키를 누르면 +1 값을 넘겨주게 됩니다
얘를 받아서
이 벡터의 방향을 만드는 데 사용하도록 할게요
얘를 그릇인 float h라는 좌우 입력에 대한
Horizontal 입력에 대한 값으로 담아둘게요
그럼 이 Horizontal 값은 어디에 있느냐면
유니티 와 보시면 Edit 메뉴에서 밑으로 쭉 내리면
Project Settings라는 게 있어요
얘를 들어가서 보면 Input Manager가 있죠
Input Manager에 Axes라는 부분이 있는데
얘를 열어보시면 여기에 Horizontal이라는 게 있습니다
이 밑에 보면 Vertical, Fire1
이렇게 미리 유니티에서 입력을 맵핑해 놓은
이런 값들을 볼 수 있을 거예요
Horizontal을 열어보면 이름은 Horizontal인데
여기에 Negative Button, left라고 되어 있고요
그다음에 Positive Button은 right라고 되어 있습니다
즉 화살표키의 왼쪽키, 오른쪽키를 뜻하는 거예요
음수, 양수를 뜻하는 거고
Alt키, 다른 대체할 수 있는 Negative 버튼은
a키, d키 이렇게
즉 그래서 왼쪽키, 오른쪽키, a키, d키를 눌렀을 때
반응하는 게 바로 Horizontal이고요
이 값은 -1에서 1 사이의 값을 넘겨주게 됩니다
여기에 정의가 되어 있는 거예요
이렇게 정의가 되어 있고
Vertical은 up, down이 되어 있고
s, w 이렇게 들어가 있죠
fire1은 뭐가 들어가 있을까요?
left ctrl키 혹은 마우스 왼쪽 버튼
0번은 마우스 왼쪽 버튼이에요
이런 식으로 값들이 정의가 되어 있습니다
여기에 정의되어 있는 값을 우리는 여기다 넣어서
작업하게 되는 거예요
이 값을 이용해서 처리해보는 값을 할 거예요
그럼 방향을 먼저 이 값을
얘가 아니라 여기에다가 넣는 값으로 바꿔보도록 할게요
그래서 우리는 Vector3에 dir을 넣도록 하고요
얘는 right죠
오른쪽 값이에요
이렇게 하면 이 dir는 오른쪽이라는 게 들어가 있고
right 대신에 이렇게만 해놓으면 어떻게 돼요?
오른쪽 방향으로 움직인다 똑같은 값이 나오겠죠
그때 우리가 여기서 사용자의 입력 값을
얘한테 적용하게 하고 싶으면
여기다가 스칼라 값인 h를 곱해 준다고 보죠
그럼 내부적으로 어떤 일이 생기죠?
right는 1, 0, 0인데
여기다가 h가 만약에 -1이에요
왼쪽 키를 눌러서 이렇게 되면
이렇게 이렇게 각각의 성분이 곱해지겠죠
그러면 어떻게 돼요?
-1, 0, 0이 돼서 왼쪽이 될 거예요
오른쪽을 누르면 +1이 돼서 그냥 1, 0, 0이 될 거고
오른쪽으로 가겠죠
아무것도 안 누르면 얘는 0 값이 들어오거든요
그러니까 방향은 0이 돼서 아무것도 안 움직이겠죠
0 × 5는 다 0이죠, 그렇죠? 그렇게 되니까
그래서 얘를 h를 여기다 곱해 주면
바로 우리가 방향을 설정할 수가 있습니다
이렇게 놓고 플레이를 한번 해보도록 할까요?
플레이
키보드의 좌우 키를 눌러볼까요?
그러면 캐릭터가, 플레이어가
좌우로 이렇게 이동하는 것을 확인할 수가 있습니다
됐죠? 그럼 상하 입력은 어떻게 할까요?
여러분들이, 아까 제가 말씀드렸던 것처럼
Input Manager에서 이 값이 뭐였죠?
Vertical이었죠, 하나 더 만들어 볼게요
v라고 놓고요 이번엔 얘를 Vertical 이렇게 놓습니다
대소문자 다 구분하셔야 돼요
그러면 사용자의 입력은 이렇게 만들어 놓는데
어? Vertical 하나를 더 하려면
방향을 하나 더 만들어서 이동시켜야 되나?
그럴 필요가 없죠
벡터의 더하기를 사용하면 돼요
어떻게? 오른쪽 방향과 위로 가는
이 두 개의 벡터를 더하면 어떻게 된다고요?
얘를 여기다가 놓을 수 있다고 했죠
그래서 이 벡터가 만들어지는 거잖아요?
그래서 두 개의 벡터를 더해버리면 되겠습니다
+ Vector3.up * v 이렇게 하시면
-1 값이 들어올 때는 아래로 들어갈 거고요 벡터가
얘는 0, 1, 0 이니까
그다음에 +1일 때는 그냥 위로 될 거고
그러면 물체를 이동시키는 이 공식을
어떻게 바꿀 수 있냐면
이렇게 만들 수가 있어요
방향을 구한다가 되는 거고요
여기까지 방향을 구하는 거고
이 밑에 있는 내용은 뭐예요?
이동시킨다
이렇게 문장을 구별해서 사용할 수가 있겠습니다
그러면 이동시킨다는
항상 이동시킨다는 단어로 끝나는 거죠
방향을 바꾸거나 여러가지 작업을 하고 싶을 때는
여기에서 코드만 바꾸게 되면 되겠습니다
함수를 만든다고 해도
이 부분의 함수만 바꿔서 만들어내면 되겠죠
이렇게 해서 사용자의 상하좌우 이동하는 것까지 해봤어요
테스트를 한번 해볼까요? 플레이
그러면 사용자가 왼쪽, 오른쪽, 상하좌우 키를 눌렀을 때
움직이는 것을 확인할 수가 있겠습니다
그럼 계속해서 이 부분을
조금 더 우리가 자세히 알아볼게요
벡터의 라이트는 어떻게 볼 수 있다고요?
벡터의 라이트는 이렇게 볼 수 있다고요
(1, 0, 0)
h까지 곱하면 어떻게 되죠?
(h, 0, 0) 이렇게 될 거예요
자 더하기 할게요
벡터의 up × v는 이렇게 볼 수 있겠네요
(0, v, 0), 자 2개를 더해봅시다
그럼 최종 값이 어떻게 나오죠? (h, v, 0)
즉 각각의 성분에다가, 이렇게 x, y, z에다가
얘를 이렇게 넣어줘도 되겠네요?
그래서 우리 코드를 이렇게도 수정할 수가 있을 거예요
이렇게 되어 있는 부분을
new Vector3에서 (h, v, 0)
이렇게 놓으셔도 내용은 똑같이 되는 거죠
저장하고 가서 또 플레이를 해볼까요
상하좌우 이동했을 때 똑같이 구현될 수가 있죠
그래서 벡터에 더하기를 해서 최종 결과물을 뽑고요
그 결과물들은 어떻게 벡터에 이런 식으로 들어가도
내용은 똑같을 수가 있겠습니다
그럼 벡터에 더하기는 필요가 없는 건가요?
이렇게 얘기하실 수도 있겠죠
아니에요 벡터에 더하기는 얘기했던 것처럼
모든 힘의 합을 구현하기 때문에 반드시 필요합니다
이건 사용자의 입력을 받아서 하나의 값으로 줄였을 때
이렇게도 사용할 수 있다는 것을 보여드릴 거예요
여러분들이 공부하시다가
유튜브나 구글 이런 데서 찾으실 때
그때 코드가 단순하게 이런 식으로만 나올 수도 있거든요
얘네는 궁극적으로 실제로는 벡터에 더하기가 근간이다
이 내용을 알아주셨으면 되겠습니다
이번 단원에서 학습한 내용을 정리하도록 하겠습니다
첫 번째로 벡터에 대해 알아봤습니다
벡터는 크기와 방향으로 이루어져 있고
더하기, 빼기, 내적, 외적의 연산을 수행할 수 있습니다
두 번째로 등속운동 공식에 대해 학습했습니다
물체 이동을 위한 등속운동 공식인
P = P0 + vt에 대해 알아봤습니다
플레이어의 이동을 제작했습니다
등속운동 공식을 바탕으로 플레이어를 이동시켰습니다
그리고 델타타임의 의미와 쓰임새에 대해 학습했습니다
사용자 입력에 따른 이동을 구현했습니다
인프 클래스를 이용해 사용자의 입력을 가져오고
사용자의 입력을 바탕으로 상하좌우 방향을 구해
플레이어의 이동을 적용했습니다
Vector의 이해 Vector Vector는 크기와 방향을 가짐 더하기, 빼기, 곱하기(내적, 외적)이 가능함 벡터의 더하기로 모든 힘의 합을 표현할 수 있음
Direction=B-A (A가 B로 가고자 하는 방향을 찾는 수식)
등속운동 공식 이해 및 플레이어 이동 제작 등속운동 물체를 이동하기 위한 물리 법칙으로 이동, 속도, 힘에 관한 공식을 사용함 P=P0+vt / v=v0+at / F=ma
델타 타임(DeltaTime) 이전 프레임과 현재 프레임 사이의 시간 PC 사양과 상관없이 초당 이동 거리를 같도록 맞추는 것이 중요함
사용자 입력에 따른 이동 구현 사용자 입력 처리 키보드의 좌우키, A, D키의 입력 대응을 위한 코드 작성
[Edit - Project Settings - Input Manager]의 속성에 등록되어 있는 Horizontal, Vertical을 활용해 상하좌우 입력에 대응하는 코드 작성
방향 만들기 '사용자 입력에 따라 방향 만들어서 이동한다'는 내용 구현
사용자 입력에서 받은 값을 방향 만들기에 사용 (Vector3 dir=Vector3.right*h+Vector3.up*v)
(h, 0, 0)+(0, v, 0)=(h, v, 0)을 이용해 스크립트를 new Vector3(h, v, 0)로 변경