-
유니티 움직임 구현 - 플레이어 이동 및 점프, 1인칭 시점Unity 2024. 1. 25. 11:06반응형
안녕하세요
오늘은 유니티 1인칭 시점 플레이어 이동 및 점프를 구현해봤습니다.
[하이어라키]
- PlayerModel은 캡슐 오브젝트를 사용했습니다
- CameraPos는 PlayerModel의 머리 부분에 위치했습니다 Position (0, 0.74, 0)
- Orientation은 Position (0, 0 ,0) 입니다.
- CameraHolder는 Position (0, 1.5, 0) 입니다.
[MoveCamera.cs]
#region 변수 [SerializeField] private Transform cameraPosition; #endregion // 변수 #region 함수 /** 초기화 => 상태를 갱신한다 */ private void Update() { transform.position = cameraPosition.position; } #endregion // 함수
- cameraPosition 변수에 MainCamera를 넣어줍니다.
- MoveCamera.cs는 CameraHolder에 넣어줍니다.
[PlayerCamera.cs]
#region 변수 [Header("=====> 감도 설정 <=====")] [SerializeField] private float mouseSensitivityX; [SerializeField] private float mouseSensitivityY; [Header("=====> 방향 <=====")] public Transform orientation; private float xRotation; private float yRotation; #endregion // 변수 #region 함수 /** 초기화 => 상태를 갱신한다 */ private void Update() { // 마우스 수평/수직 float mouseX = Input.GetAxisRaw("Mouse X") * mouseSensitivityX; float mouseY = Input.GetAxisRaw("Mouse Y") * mouseSensitivityY; // 마우스가 위로 올라갈 때 X가 바뀜 yRotation += mouseX; xRotation -= mouseY; // 수직회전 고정 xRotation = Mathf.Clamp(xRotation, -90f, 90f); // 회전 적용 transform.rotation = Quaternion.Euler(xRotation, yRotation, 0); orientation.rotation = Quaternion.Euler(0, yRotation, 0); } #endregion // 함수
- mouseSensitivity는 직접 테스트해보면서 조절하시면 됩니다.
- orientation은 Player객체 하위에 있는 Orientation 객체를 넣어주면 됩니다.
- PlayerCamera.cs는 MainCamera에 넣어줍니다.
[PlayerMovemenet.cs]
#region 변수 [Header("=====> 이동 <=====")] [SerializeField] private float moveSpeed; [SerializeField] private float correctMoveSpeed; [SerializeField] private float baseDrag; [SerializeField] private Transform orientation; [Header("=====> 점프 설정 <=====")] [SerializeField] private float jumpPower; [SerializeField] private float jumpCooldown; [SerializeField] private float playerHeight; [SerializeField] private float correctPlayerHeight; [SerializeField] private LayerMask groundLayer; [Header("=====> 키 입력 <=====")] [SerializeField] private KeyCode jumpKey = KeyCode.Space; [Header("=====> 인스펙터 값 확인 <=====")] [SerializeField] private float airMultiplier; private bool isJump; private bool isGround; private float horizontalInput; private float verticalInput; private Vector3 moveDirection; private Rigidbody rigid; #endregion // 변수 #region 함수 /** 초기화 */ private void Awake() { rigid = GetComponent<Rigidbody>(); rigid.freezeRotation = true; // 점프 초기화 PlayerResetJump(); } /** 초기화 => 상태를 갱신한다 */ private void Update() { // 오브젝트의 높이 절반 + 보정값 isGround = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + correctPlayerHeight, groundLayer); // 플레이어 입력처리 PlayerInput(); // 플레이어 속도제어 PlayerSpeedControl(); // 저항 값 제어 DragAirControl(); } /** 초기화 => 상태를 갱신한다 */ private void FixedUpdate() { // 플레이어 이동 PlayerMove(); } /** 입력처리 */ private void PlayerInput() { // 움직임 horizontalInput = Input.GetAxisRaw("Horizontal"); verticalInput = Input.GetAxisRaw("Vertical"); // 점프 if(Input.GetKey(jumpKey) && isJump && isGround) { isJump = false; // 점프 PlayerJump(); // 점프 쿨타임 Invoke(nameof(PlayerResetJump), jumpCooldown); } } /** 플레이어 이동 */ private void PlayerMove() { // 이동방향 계산 moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput; // 이동 rigid.AddForce(moveDirection.normalized * moveSpeed * correctMoveSpeed * airMultiplier, ForceMode.Force); } /** 플레이어 속도제어 */ private void PlayerSpeedControl() { // 속도 Vector3 currentVelocity = new Vector3(rigid.velocity.x, 0f, rigid.velocity.z); // 현재 속도가 이동속도보다 클 경우 if(currentVelocity.magnitude > moveSpeed) { // 같은 방향 moveSpeed로 크기 제한 Vector3 limitVelocity = currentVelocity.normalized * moveSpeed; rigid.velocity = new Vector3(limitVelocity.x, rigid.velocity.y, limitVelocity.z); } } /** 플레이어 점프 */ private void PlayerJump() { rigid.velocity = new Vector3(rigid.velocity.x, 0f, rigid.velocity.z); rigid.AddForce(transform.up * jumpPower, ForceMode.Impulse); } /** 점프 초기화 */ private void PlayerResetJump() { isJump = true; } /** 저항 값 제어 */ private void DragAirControl() { // 공기저항 rigid.drag = isGround ? baseDrag : 1; // 점프했을때 안했을때 움직이는 속도 조정 airMultiplier = isGround ? 1 : (1 / (baseDrag + 1)); } #endregion // 함수
- playerHeight는 오브젝의 높이를 구하여 설정해주시면 됩니다. 캡슐 오브젝트의 높이는 2 입니다.
- correct 변수는 보정값입니다.
- PlayerMovement.cs는 Player에 넣어줍니다.
[인스펙터]
[추가 설정]
- Layer에 Ground를 추가하시고 바닥이 되는 객체의 Layer를 Ground로 바꿔 주시면 됩니다.
반응형'Unity' 카테고리의 다른 글
유니티 FSM 유한 상태 머신 - 몬스터 상태 관리 (0) 2024.03.19 유니티 웅크리기 구현 - 플레이어 웅크리기 (0) 2024.02.03 유니티 인벤토리 - 인벤토리 시스템 (0) 2024.01.23 유니티 데이터 저장/불러오기 - Json 데이터 저장/불러오기 (0) 2024.01.22 유니티 DOTween - 알림창 만들기 (0) 2024.01.18