[TIL] 유니티(Unity) 플레이어 이동 & 카메라 컨트롤

백성은·2025년 5월 16일

TIL

목록 보기
26/34

✅ 학습한 주요 내용

  • Rigidbody 기반 플레이어 이동
  • 마우스 입력, 카메라 회전
  • Raycast로 착지 판정

✅ Rigidbody 기반 플레이어 이동

  • transform.forward, transform.right를 이용해 방향 벡터 계산
  • Rigidbody.velocity에 직접 속도 할당하여 부드러운 물리 이동

예시

    void Move()
    {
    	// 입력된 y값을 z축(앞뒤), x값을 x축(좌우)에 반영하여 이동 방향 계산
        Vector3 dir = transform.forward * curMovementInput.y + transform.right * curMovementInput.x;
        // 이동 속도 적용
        dir *= moveSpeed;
        // y축 속도는 중력 영향을 받게 기존 Rigidbody y속도를 유지
        dir.y = _rigidbody.velocity.y;

		// 계산된 방향 벡터를 실제 물리 속도로 반영
        _rigidbody.velocity = dir;
    }
    
    	// InputAction.CallbackContext는 입력 이벤트에 대한 정보(값, 상태 등)를 담고 있음
        public void OnMove(InputAction.CallbackContext context)
    {
    	// context의 상태와 InputActionPhase.Performed(입력중)라는 enum 값을 비교
        if (context.phase == InputActionPhase.Performed)
        {
            curMovementInput = context.ReadValue<Vector2>();
        }
    	// context의 상태와 InputActionPhase.Canceled(입력되지않음)라는 enum 값을 비교
        else if (context.phase == InputActionPhase.Canceled)
        {
            curMovementInput = Vector2.zero;
        }
    }

✅ 2. 마우스 입력, 카메라 회전

  • InputAction.CallbackContext로 마우승 움직임 입력(mouseDelta) 받기
  • camCurXRot += mouseDelta.y * sensitivity로 회전
  • X축 회전(상하 시야)은 카메라 컨테이너, Y축 회전(좌우 시야)은 플레이어에 적용
    void CameraLook()
    {
    	// 마우스의 Y 이동값에 감도를 곱해서 상하 회전 각도를 누적
        camCurXRot += mouseDelta.y * lookSensitivity;
        // camCurXRot 값이 너무 위나 아래로 꺾이지 않게 최소/최대값 제한
        camCurXRot = Mathf.Clamp(camCurXRot, minXLook, maxXLook);
        // 카메라 컨테이너의 회전을 camCurXRot만큼 적용 (상하 회전)
        cameraContainer.localEulerAngles = new Vector3(-camCurXRot, 0, 0);
		
        // 플레이어 오브젝트의 Y 회전에 마우스 X 이동값을 적용 (좌우 회전)
        transform.eulerAngles += new Vector3(0, mouseDelta.x * lookSensitivity, 0);
    }
    
    public void OnLook(InputAction.CallbackContext context)
    {
        mouseDelta = context.ReadValue<Vector2>();
    }

마우스를 Y축 이동은 X축 회전이므로 -camCurXRot를 적용해야 상하 카메라 회전이 된다

✅ 3.Raycast로 착지 판정

  • 플레이어 위치 주변 4방향에서 아래로 Ray를 쏘면서 감지
  • Physics.Raycast(ray, 0.1f. groundLayerMask)를 통해 점프 가능 여부 판단
    public void OnJump(InputAction.CallbackContext context)
    {
    	// 입력이 시작될 때와 착지 상태일때
        if (context.phase == InputActionPhase.Started && IsGrounded())
        {
        	// 위쪽 방향으로 점프 힘을 가함 (Impulse로 순간적인 힘을 가함)
            _rigidbody.AddForce(Vector2.up * jumpPower, ForceMode.Impulse);
        }
    }
	bool IsGrounded()
	{
    	// 플레이어의 네 방향에서 아래로 향하는 Ray를 약간위에서 생성해서 바닥과 닿는지 확인
    	Ray[] rays = new Ray[4]
    	{
        	new Ray(transform.position + (transform.forward * 0.2f) + (transform.up * 0.01f), Vector3.down),
        	new Ray(transform.position + (-transform.forward * 0.2f) + (transform.up * 0.01f), Vector3.down),
        	new Ray(transform.position + (transform.right * 0.2f) + (transform.up * 0.01f), Vector3.down),
        	new Ray(transform.position + (-transform.right * 0.2f) + (transform.up * 0.01f), Vector3.down),
    	};
		// 생성한 네 개의 Ray 중 하나라도 바닥에 닿으면 true 반환
    	foreach (Ray ray in rays)
    	{
        	if (Physics.Raycast(ray, 0.1f, groundLayerMask))
            	return true;
    	}
        // 네 개의 Ray 모두 닿지 않았으면 공중에 떠 있는 상태
    	return false;
	}

📝 느낀점

3D 개발이다 보니 축이 하나 더 늘어나서, 2D로 학습하던 때보다 상대적으로 더 복잡하고 어려운 부분이 있는 것 같다. 특히 회전이나 방향 처리에서 X, Y, Z축 개념을 정확히 이해하지 않으면 헷갈리기 쉬웠다. 그래도 Raycast 같은 새로운 개념들을 배우면서, 3D에서만 할 수 있는 판정 방식이나 표현들이 신기하고 흥미롭게 느껴졌다.

profile
게임 개발일지

0개의 댓글