전체 코드
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class PlayerController : MonoBehaviour | |
{ | |
[SerializeField] | |
private float walkSpeed; | |
// 카메라의 민감도 | |
[SerializeField] | |
private float lookSensitivity; | |
// 카메라의 각도 | |
[SerializeField] | |
private float cameraRotationLimit; | |
private float currentCameraRotationX = 0; | |
[SerializeField] | |
private Camera theCamera; | |
private Rigidbody myRigid; | |
// Start is called before the first frame update | |
void Start() | |
{ | |
myRigid = GetComponent<Rigidbody>(); | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
Move(); | |
CameraRotation(); | |
CharacterRotation(); | |
} | |
private void Move() | |
{ | |
float _moveDirX = Input.GetAxisRaw("Horizontal"); | |
float _moveDirZ = Input.GetAxisRaw("Vertical"); | |
Vector3 _moveHorizontal = transform.right * _moveDirX; | |
Vector3 _moveVertical = transform.forward * _moveDirZ; | |
Vector3 _velocity = (_moveHorizontal + _moveVertical).normalized * walkSpeed; | |
myRigid.MovePosition(transform.position + _velocity * Time.deltaTime); | |
} | |
private void CharacterRotation() | |
{ | |
float _yRotation = Input.GetAxisRaw("Mouse X"); | |
Vector3 _characterRotationY = new Vector3(0f, _yRotation, 0f) * lookSensitivity; | |
myRigid.MoveRotation(myRigid.rotation * Quaternion.Euler(_characterRotationY)); | |
} | |
private void CameraRotation() | |
{ | |
float _xRotation = Input.GetAxisRaw("Mouse Y"); | |
float _cameraRotationX = _xRotation * lookSensitivity; | |
currentCameraRotationX -= _cameraRotationX; | |
currentCameraRotationX = Mathf.Clamp(currentCameraRotationX, -cameraRotationLimit, cameraRotationLimit); | |
theCamera.transform.localEulerAngles = new Vector3(currentCameraRotationX, 0f, 0f); | |
} | |
} |
구현 영상

- wasd 혹은 화살표 방향키로 캐릭터가 움직이게 구현
- 마우스의 이동으로 캐릭터의 시선이 움직이게 구현
코드 설명
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[SerializeField] | |
private float walkSpeed; |
- private로 설정해주게 되면, Unity의 Inspector 창에서 보이지 않게 된다.
- 만약, private -> public으로 바꿔주게 되면, Inspector 창에서 보이게 된다.
- 그리고 이때, [SerializeField]를 설정해주게 되면, 보호 수준은 유지되면서, Inspector 창에서 수정이 가능하게 한다.
- 또한, [SerializeField]는 데이터 직렬화, 이진화로 만드는 작업을 포함한다.
└ 나중에 save 할 때 유용하다. - [SerializeField]를 넣는다고 무조건 인스펙터 창에 뜨지는 않는다. 예외도 있다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private Rigidbody myRigid; |
- Rigidbody는 플레이어의 실제 육체적인 몸을 의미한다.
- 만약 Rigidbody를 선언해주지 않게 되면, 플레이어의 겉모습만 보여줄 뿐 투명하게 통과되게 된다.

- 따라서, Rigidbody를 선언해주고 나면, 위의 사진과 같이 캐릭터 안에 Rigidbody를 넣어주어야 한다.
- 이렇게 되면, 물리적인 몸(보여질 뿐만 아니라, 캐릭터가 통과가 안되는)이 구성된다.
- Mass : 질량 / Drag : 저항 (바람 등과 같은) / Angular Drag : 밀려나는 저항 / Use Gravity : 중력 영향 / Is Kinematic : 역학 관련된 것
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Start() | |
{ | |
myRigid = GetComponent<Rigidbody>(); | |
} |
- Start()는 해당 스크립트가 처음 시작될 때 실행되는 내장함수이다. (기본으로 제공되는 메서드)
- Unity의 Rigidbody 컴포넌트를 myRigid 변수에 넣겠다는 의미이다.
[SerializeField]
private Rigidbody myRigid
- [SerializeField]을 사용하는 방식보다 위의 방법이 좀 더 빠르다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Update() | |
{ | |
// ... | |
} |
- Update()는 매 프레임마다 호출되는 함수이다.
- 컴퓨터 환경마다 다르지만, 보통 1초에 대략 60번이 실행된다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void Move() | |
{ | |
float _moveDirX = Input.GetAxisRaw("Horizontal"); | |
float _moveDirZ = Input.GetAxisRaw("Vertical"); | |
Vector3 _moveHorizontal = transform.right * _moveDirX; | |
Vector3 _moveVertical = transform.forward * _moveDirZ; | |
Vector3 _velocity = (_moveHorizontal + _moveVertical).normalized * walkSpeed; | |
myRigid.MovePosition(transform.position + _velocity * Time.deltaTime); | |
} |
- _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 해줘야 한다.

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[SerializeField] | |
private float lookSensitivity; |
- lookSensitivity : 카메라의 민감도를 의미한다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[SerializeField] | |
private float cameraRotationLimit; | |
private float currentCameraRotationX = 0; |
- cameraRotationLimit : 캐릭터의 고개의 각도를 제한하기 위해 사용된다.
└ 만약, 캐릭터의 고개를 제한하지 않으면, 캐릭터는 360도로 고개를 돌릴 수 있게 된다. - currentCameraRotationX : 캐릭터가 바라보는 방향의 각도, 0은 기본값이라 생략해도 된다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[SerializeField] | |
private Camera theCamera; |
- theCamera : Camera 컴포넌트를 불러온다.
- Player에는 Camera 컴포넌트가 없고, Player 안에 있는 자식 객체에 있다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Start() | |
{ | |
theCamera = FindObjectOfType<Camera>(); | |
} |
- FindObjectType를 이용하여 모든 객체들을 조사하여 Camera 컴포넌트가 있으면 theCamera에 넣어주는 방식이다.
- 하지만, Camera가 한 개가 아닌 여러 개가 있을 수 있기 때문에 이 방법은 올바른 방법이 아니다.
- 따라서, 아래와 같이 설정해주어야 한다.

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void CameraRotation() | |
{ | |
float _xRotation = Input.GetAxisRaw("Mouse Y"); | |
float _cameraRotationX = _xRotation * lookSensitivity; | |
currentCameraRotationX -= _cameraRotationX; | |
currentCameraRotationX = Mathf.Clamp(currentCameraRotationX, -cameraRotationLimit, cameraRotationLimit); | |
theCamera.transform.localEulerAngles = new Vector3(currentCameraRotationX, 0f, 0f); | |
} |
- _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로 표현하게 한다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void CharacterRotation() | |
{ | |
float _yRotation = Input.GetAxisRaw("Mouse X"); | |
Vector3 _characterRotationY = new Vector3(0f, _yRotation, 0f) * lookSensitivity; | |
myRigid.MoveRotation(myRigid.rotation * Quaternion.Euler(_characterRotationY)); | |
} |
- CharacterRotation()은 좌우 캐릭터 회전의 역할을 하는 함수이다.
- movePosition()은 Vector3, moveRotation은 Quaternion을 인자로 받는다.
- myRigid.rotation * Quaternion.Euler(_characterRotationY)의 결과 플레이어가 회전하게 할 수 있다.
'Unity' 카테고리의 다른 글
Unity_Survival_Game02 - 심화 캐릭터 움직이기 (달리기, 앉기, 점프하기) (0) | 2022.08.05 |
---|