[Unity] New Input System으로 1인칭 플레이어 점프/카메라 회전
New Input System과 기본적인 플레이어 움직임에 관한 글은 아래 블로그를 참고
2025.03.04 - [Unity] - [Unity] New Input System 으로 플레이어 움직이기
[Unity] New Input System 으로 플레이어 움직이기
1. New Input System2. New Input System 사용방법3. PlayerController 스크립트4. PlayerInput 컴포넌트📝 New Input System이란? Unit
youcheachae.tistory.com
📝 플레이어 Jump
상단의 링크에서 작성한 PlayerMove 스크립트에서 추가로 작성해주었다.
// ....
#region 플레이어 점프
public void OnJump(InputAction.CallbackContext context)
{
// 한번 눌리면
if(context.phase == InputActionPhase.Started)
{
playerRb.velocity = Vector3.zero;
playerRb.AddForce(Vector3.up * 5f , ForceMode.Impulse);
}
}
#endregion
// ....
□ OnJump()
■ PlayInput컴포넌트에서 입력 발생 시 리턴되는 콜백을 받아오기 위한 함수 작성
■ 매개변수를 InputAction.CallbackContext로 콜백을 받아온다
■ 입력이 눌렸을 때, 플레이어의 Vector3.Up방향(0,1,0)으로 , Addforce 해준다.
□ 컴포넌트의 Event → Player → Jump Aciont에 (+) 버튼으로 추가해 준다
□ Player 오브젝트를 드래그해서 넣고, PlayerController스크립트의 OnJump메서드를 추가한다
📝 발생한 문제
□ 열심히 스페이스바를 누르고 있지만 플레이어에 Addforce가 적용되지 않는 모습이다.
🔖 해결시도
1. Mass를 줄이기 / 늘리기
■ Mass는 오브젝트 질량 이기 때문에 질량을 줄이면 느리게 떨어지고, 늘리면 빨리 떨어질 거라 생각했다.
하지만 Mass를 변경해도 떨어지는 속도가 변하지 않았다.
2. 중력 Scale을 수정
■ Edit → Project Setting →Physics의 Gravity를 -24 정도까지 줄여봤다.
: 하지만 이것 또한 플레이어가 떨어지는 속도가 변하지 않았다.
3. 테스트로 만들어놓은 큐브와 컴포넌트 하나하나 비교해 보기....
: 테스트용 큐브와 플레이어의 차이는 PlayerController밖에 없는데,
혹시 여기서 문제인가...?! 싶어서 코드를 다시 뜯어봤다.
- 그 당시 PlayerMove() 코드
private void PlayerMove()
{
Vector3 dir = transform.forward * moveVector.y + transform.right * moveVector.x;
dir *= speed;
playerRb.velocity = dir;
}
: 해당 코드에서 , y값의 속력을 지정해 주는 부분이 없다!!
그래서 y의 속력이 항상 0으로 설정되고 , 그래서 Gravity값과 Mass를 아무리 수정해도 변화가 없었던 것.............
- 해결 방법
🔖 dir의 y는 현재 물리엔진에서 계산되고 있는 중력이나 점프 등으로 발생한 y 방향의 속도를 유지하기 위해서 playerRB.velocity.y로 설정해 주면 된다.
dir.y = playerRB.velocity.y;
y 속도를 생각하지 못한 내 실수였던 것....
: 상단의 링크에서 작성한 코드 PlayerMove()에 대해 추가적인 설명을 하고 넘어가려 한다.
전체적인 코드는 상단의 링크를 참고!
private void Move()
{
Vector3 dir = transform.forward * curMoveInput.y + transform.right * curMoveInput.x;
dir *= _moveSpeed;
dir.y = playerRB.velocity.y;
playerRB.velocity = dir;
}
□ curMoveInput은 Vector2 타입으로, x와 y 밖에 없다.
□ Vector2에서 움직일 때, 플레이어 기준 앞 / 뒤로 움직이면 y 값이 변화한다. 좌 / 우로 움직이면 x 값이 변화한다.
■ y가 양수면 앞쪽으로 이동
■ y가 음수면 뒤쪽으로 이동
■ x가 양수면 오른쪽으로 이동
■ x가 음수면 왼쪽으로 이동
□ Vector3에서 움직일 때, 플레이어 기준 앞 / 뒤로 움직이면 z 값이 변화한다. 좌 / 우로 움직이면 x 값이 변화한다.
□ 플레이어 기준 앞/뒤 움직임이 발생하면 플레이어 앞쪽(forward)과 y값을 곱하고, 좌/우 움직임이 발생하면 플레이어의 오른쪽 (right)과 x 값을 곱해서 가야 할 방향을 나타낸다.
□ y는 위에서 설명한 대로, 현재 물리엔진에서 계산되고 있는 중력이나 점프 등으로 발생한 y 방향의 속도를 유지하기 위해서 playerRB.velocity.y로 설정해 주면 된다.
📝 마우스에 따른 플레이어 회전 / 카메라 회전
접근방식
마우스를 회전하면, 플레이어의 x회전과 y 회전을 변경시켜야 된다고 생각했다.
하지만 플레이어의 x값 회전을 하면 플레이어의 콜라이더가 땅에 박히거나 충돌 나는 문제가 발생할 것 같았다.
: 콜라이더가 땅에 박힌다....
즉 , 마우스를 회전하면
1. 플레이어의 y 회전 값 (좌, 우)이 변경되어야 한다.
2. 카메라의 x 회전 값 (상, 하)이 변경되어야 한다.
- 구체적인 코드
[Header("===Rotate===")]
[SerializeField] private Vector2 mouseDelta; // 마우스 움직임 델타
[SerializeField] private float currentY; // 현재 회전 상태 Y
[SerializeField] private float rotationBoundary = 80f;
[SerializeField] private float sensitivity;
private void LateUpdate()
{
RotateCamera();
}
private void RotateCamera()
{
// 플레이어는 rotation의 y값만 바껴야한다
// 카메라는 rotation의 x값만 바껴야 한다
currentY += mouseDelta.y * sensitivity;
float newY = Mathf.Clamp(currentY, -rotationBoundary , rotationBoundary) ;
// 카메라 회전
cameraTrs.localEulerAngles = new Vector3( -newY, 0, 0);
// 플레이어 회전
transform.eulerAngles += new Vector3(0, mouseDelta.x * sensitivity, 0);
}
public void OnRotateCamera(InputAction.CallbackContext context)
{
// Delta값 :
// 화면의 중앙을 (0, 0) 기준으로
// 마우스를 빠르게 움직일수록 절대값이 커짐
// 마우스를 오른쪽으로 빠르게 이동: (15, 0)
// 마우스를 왼쪽으로 천천히 이동: (-2, 0)
mouseDelta = context.ReadValue<Vector2>();
// Debug.Log($"Mouse Delta: {mouseDelta}");
}
□ OnRotateCamera()
■ context.ReadValue <Vector2>()로 마우스 움직임에 관한 Vector2 값을 mouseDelta 변수에 저장한다.
□ RotateCamera()
■ 카메라 회전을 계산하기 위해서 입력받은 mouseDelta값의 y에 sensitivity값을 곱해서 저장한다.
■ 카메라 회전 (위, 아래)는 너무 큰 값이 들어가면 360도 돌 수 있기 때문에 임시로 -80 ~ 80까지 값으로 설정했다.
■ localEulerAngles를 사용해서 회전값을 적용한다.
□ 카메라는 현재 Player 하위에 있기 때문에 local 회전값을 변경시켜 준다
□ 카메라의 회전값을 변경하면 (-) 값으로 들어가서 코드상에서 (- ) 값을 넣어준다
■ 플레이어 회전 (좌, 우)는 mouseDelta값의 x로 설정한다.
📝 플레이어 움직임/점프/카메라 회전 결과
원하던 움직임이 잘 나타나는 것을 확인할 수 있다.
https://github.com/kimYouChae/Sparta_OnlyUp