Unity
유니티 움직임 구현 - 플레이어 이동 및 점프, 1인칭 시점
Lavin
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로 바꿔 주시면 됩니다.
반응형