전체 코드
구현 영상
- wasd 혹은 화살표 방향키로 캐릭터가 움직이게 구현
- 마우스의 이동으로 캐릭터의 시선이 움직이게 구현
코드 설명
- private로 설정해주게 되면, Unity의 Inspector 창에서 보이지 않게 된다.
- 만약, private -> public으로 바꿔주게 되면, Inspector 창에서 보이게 된다.
- 그리고 이때, [SerializeField]를 설정해주게 되면, 보호 수준은 유지되면서, Inspector 창에서 수정이 가능하게 한다.
- 또한, [SerializeField]는 데이터 직렬화, 이진화로 만드는 작업을 포함한다.
└ 나중에 save 할 때 유용하다. - [SerializeField]를 넣는다고 무조건 인스펙터 창에 뜨지는 않는다. 예외도 있다.
- Rigidbody는 플레이어의 실제 육체적인 몸을 의미한다.
- 만약 Rigidbody를 선언해주지 않게 되면, 플레이어의 겉모습만 보여줄 뿐 투명하게 통과되게 된다.
- 따라서, Rigidbody를 선언해주고 나면, 위의 사진과 같이 캐릭터 안에 Rigidbody를 넣어주어야 한다.
- 이렇게 되면, 물리적인 몸(보여질 뿐만 아니라, 캐릭터가 통과가 안되는)이 구성된다.
- Mass : 질량 / Drag : 저항 (바람 등과 같은) / Angular Drag : 밀려나는 저항 / Use Gravity : 중력 영향 / Is Kinematic : 역학 관련된 것
- Start()는 해당 스크립트가 처음 시작될 때 실행되는 내장함수이다. (기본으로 제공되는 메서드)
- Unity의 Rigidbody 컴포넌트를 myRigid 변수에 넣겠다는 의미이다.
[SerializeField]
private Rigidbody myRigid
- [SerializeField]을 사용하는 방식보다 위의 방법이 좀 더 빠르다.
- Update()는 매 프레임마다 호출되는 함수이다.
- 컴퓨터 환경마다 다르지만, 보통 1초에 대략 60번이 실행된다.
- _moveDirX : 우측과 좌측을 의미한다.
- Input : 입력이 주어졌을 때를 의미한다.
- GetAxisRaw("Horizontal") : 키보드의 좌우 화살표 / a, d를 누르게 되면 -1과 1이 리턴된다.
└ 오른쪽 방향키 : 1 / 왼쪽 방향키 : -1 / 안누를 때 : 0 이 리턴된다. - Horizontal은 Unity에서 기본적으로 Horizontal이라고 명시해놨기 때문에, Horizontal이라고 써야 좌우 화살표 / a, d를 받아올 수 있게 된다.
└ 옵션에서 Horizontal을 다른것으로 설정 가능함 ! - _moveDirZ : 정면과 뒤를 의미한다.
└ Y는 점프했을 때의 공중을 의미함. - Vector3 : float 값을 3개 가지는 변수를 의미한다.
- transform : Unity에서 컴포넌트가 가지고 있는 위치 값, 회전 값을 가지고 있다.
┌ transform.right에는 기본적으로 (1, 0, 0)을 가지고 있다.
├ 이 때, 오른쪽 버튼을 누르게 되면 (1, 0, 0) * 1 => 오른쪽 방향으로 이동
├ 왼쪽 버튼을 누르게 되면 (1, 0, 0) * -1 => 왼쪽 방향으로 이동
├ transform.forward에는 기본적으로 (0, 0, 1)을 가지고 있다.
├ 이 때, 앞쪽 버튼을 누르게 되면 (0, 0, 1) * 1 => 앞으로 이동
└ 뒤쪽 버튼을 누르게 되면 (0, 0, 1) * -1 => 뒤로 이동 - _velocity : 속도를 의미한다.
- normalized : 합이 1이 나오도록 정규화 시켜주게 된다.
└ normalized 해주는 이유 : 유니티 상에서는 합을 1로 만드는 것을 권장하고,
이는 내부 알고리즘 적으로 더 빠르다.
또한, 우리의 입장에서도 1초에 얼마나 이동시킬 건지에 대한 계산이 편해진다. - Time.deltaTime : n만큼의 거리를 1초동안 움직이게 끔 만들어주는 역할을 한다.
└ Time.deltaTime을 안써주게 되면, 캐릭터가 순간이동하는 것을 볼 수 있다.
하지만, 이 상태에서 실행을 시키게 되면 아래와 같이 캐릭터가 쓰러지게 된다.
따라서, 캐릭터가 쓰러지지 않게 하기 위해서는 아래와 같이 X와 Z의 Rotation을 Freeze 해줘야 한다.
- lookSensitivity : 카메라의 민감도를 의미한다.
- cameraRotationLimit : 캐릭터의 고개의 각도를 제한하기 위해 사용된다.
└ 만약, 캐릭터의 고개를 제한하지 않으면, 캐릭터는 360도로 고개를 돌릴 수 있게 된다. - currentCameraRotationX : 캐릭터가 바라보는 방향의 각도, 0은 기본값이라 생략해도 된다.
- theCamera : Camera 컴포넌트를 불러온다.
- Player에는 Camera 컴포넌트가 없고, Player 안에 있는 자식 객체에 있다.
- FindObjectType를 이용하여 모든 객체들을 조사하여 Camera 컴포넌트가 있으면 theCamera에 넣어주는 방식이다.
- 하지만, Camera가 한 개가 아닌 여러 개가 있을 수 있기 때문에 이 방법은 올바른 방법이 아니다.
- 따라서, 아래와 같이 설정해주어야 한다.
- _xRotation에서 Mouse Y를 가져오는 이유는 마우스는 3차원이 아닌 X와 Y만 있는 2차원이기 때문이다.
└ Mouse Y : 마우스를 위아래로 움직일 때 - _cameraRotationX : lookSensitivity를 곱하여 카메라를 어느 정도 천천히 움직이게 만든다.
- currentCameraRotation X += _cameraRotationX; 에서 +는 흔히 FPS 게임류 옵션에 있는 마우스 Y 반전과 관련이 있다.
- currentCameraRotationX += _cameraRotationX; 로 설정해주었을 때의 영상이다.
- 즉, 마우스를 아래로 이동하면 카메라가 위로 향하게 되고,
- 마우스를 위로 이동하면 카메라가 아래로 향하게 된다.
- 따라서, currentCameraRotationX -= _cameraRotationX;로 설정해주어야 정상적으로 원하는 상하의 방향으로 움직이게 된다.
- Mathf.Clamp : 가두는(?) 역할, 즉 currentCameraRotationX 값이 -cameraRotationLimit과 cameraRotationLimit 사이에 고정이 되게 가둔(제한)다.
└ 즉, cameraRotationLimit을 45˚라고 한다면, 70˚가 되어도 45˚로 고정한다. - theCamera.transform : 카메라의 위치 정보를 의미한다.
- localEulerAngles : Rotation X, Y, Z를 생각하면 된다.
└ 내부적으로는 Euler 값이 Quaternion형으로 4원소를 갖는데, 크게 X, Y, Z로 표현하게 한다.
- CharacterRotation()은 좌우 캐릭터 회전의 역할을 하는 함수이다.
- movePosition()은 Vector3, moveRotation은 Quaternion을 인자로 받는다.
- myRigid.rotation * Quaternion.Euler(_characterRotationY)의 결과 플레이어가 회전하게 할 수 있다.
'Unity' 카테고리의 다른 글
Unity_Survival_Game02 - 심화 캐릭터 움직이기 (달리기, 앉기, 점프하기) (0) | 2022.08.05 |
---|