C#/Unity 3D

[Unity 3D] [Starter Assets] (4) ThirdPersonController : 점프(GroundedCheck & JumpAndGravity) 코드 분석

hizzi 2024. 4. 4. 17:45

 

더보기

목차

  • GroundedCheck() 역할
  • GroundedCheck() 변수 설명
  • GroundedCheck() 함수 코드 분석
  • JumpAndGravity() 역할
  • JumpAndGravity() 변수 설명
  • JumpAndGravity() 함수 코드 분석

1. GroundedCheck() 역할

  Player가 땅을 밟고 있는지에 따라 전역변수인 Grounded를 true/false로 설정한다.

  (땅을 밟고 있는 경우 true, 점프 및 공중에 떠있지 않은 경우 false)

 

2. GroundedCheck() 변수 설명

 

  • Grounded : Player가 원하는 오브젝트와 맞닿아 있는가(접지되어 있는가) 여부를 판단한다.
  • Grounded Offset : 거친 땅의 경우 Offset을 이용하여 Grounded 체크한다.
  • Grounded Radius : Grounded의 반경으로, CharacterController의 반경과 일치해야 한다.
  • Grounded Layers : 땅으로 설정할 Layer

 

3. GroundedCheck() 함수 코드 분석

 

private void GroundedCheck()
{
    // offset을 사용하여 구의 위치 설정
    Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset,
    transform.position.z);

    // GroundLayers와 player가 겹치면 true 반환
    Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers,
        QueryTriggerInteraction.Ignore);

    if (_hasAnimator)
    {
        _animator.SetBool(_animIDGrounded, Grounded);
    }
}
  • Physics.CheckSphere : transform.position에 의해 정의된 구와 겹치는 충돌체가 있는 경우 true 반환한다.
  • Grounded에 따라 _animIDGrounded(애니메이션)를 적용시킨다.

4. JumpAndGravity() 역할

  Grounded에 따라 Jump/Fall Timeout을 설정하고 수직 속도/중력에 맞게 애니메이션을 적용한다.

 

5.JumpAndGravity() 변수 설명

 

    • Jump Height : Jump시 도달할 최고 높이
    • Gravity : 중력
    • Jump TimeOut : 다시 Jump하기까지 걸리는 시간, 다시 점프하려면 0f로 설정해야 한다.
    • Fall TimeOut : 떨어지는 상태의 시작까지 소요되는 시간

 

6.JumpAndGravity() 함수 코드 분석

 

(1) Grounded

//땅을 밟고 있는 경우
if (Grounded)
{
    // fallTimeoutDelta 재설정
    _fallTimeoutDelta = FallTimeout;

    // 점프 모션과 떨어지는 모션 제거
    if (_hasAnimator)
    {
        _animator.SetBool(_animIDJump, false);
        _animator.SetBool(_animIDFreeFall, false);
    }

    // 땅에 닿았을 때, 속도(수직)가 무한히 떨어지는 것을 방지함
    if (_verticalVelocity < 0.0f)
    {
        _verticalVelocity = -2f;
    }

    // Jump 시작
    if (_input.jump && _jumpTimeoutDelta <= 0.0f)
    {
        // 원하는 높이에 도달할 때 필요한 속도
        _verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity);

        // 점프 모션 적용
        if (_hasAnimator)
        {
            _animator.SetBool(_animIDJump, true);
        }
    }

    // 올라가는 JumpTimeout
    if (_jumpTimeoutDelta >= 0.0f)
    {
        _jumpTimeoutDelta -= Time.deltaTime;
    }
}

 

  • Grounded인 경우(이동 혹은 Jump 시작과 끝),  FallTimeOut 초기화 및 공중에서 모션(점프/떨어지는 중)을 제거한다.
  • 땅에 닿아있다면(Jump 시작/끝), 수직 속도가 떨어지지 않아야 하므로 무한히 떨어지는 것을 방지한다.
  • Jump가 true 상태면, 원하는 높이(최고 높이)에 도달할 때 필요한 속도를 설정하고 Jump 모션을 적용한다.

 

(2) !Grounded(Grounded == false)

else
{
   // JumpTimeoutDelta 재설정
   _jumpTimeoutDelta = JumpTimeout;

   // 땅 -> 최고 높이로 도달하기 까지
   if (_fallTimeoutDelta >= 0.0f)
   {
       _fallTimeoutDelta -= Time.deltaTime;
   }
   // 최고 높이 -> 땅으로 도달하기 까지
   else
   {
        // 떨어지는 모션 적용
        if (_hasAnimator)
        {
            _animator.SetBool(_animIDFreeFall, true);
        }
    }

    _input.jump = false;
}

 

  • !Grounded인 경우(Jump 중),  JumpTimeOut 초기화
  • 땅에서 최고 높이까지 도달할 때 : FallTimeOut을 감소시킨다.
  • 최고 높이에서 땅으로 내려갈 때 : 떨어지는 모션을 적용한다.

 

(3) 중력 적용

 

// 중력 적용
if (_verticalVelocity < _terminalVelocity)
{
    _verticalVelocity += Gravity * Time.deltaTime;
}
  • terminal 속도보다 수직 속도가 작은 경우, 중력을 적용한다.

 

사담

  지금까지 분석했던 함수 중에 JumpAndGravity가 가장 복잡했던 것 같습니다. 나름 분석해보았지만 잘못된 지식이 있다면 댓글 부탁드리겠습니다!

  또한, Unity 3D 관련하여 원하는 주제가 있다면 자유롭게 요청 부탁드립니다 ㅎㅎ!

  다음은 투명 벽 생성을 해보려고 합니다~ 다들 즐거운 코딩합시다!