Unity - 2D 플랫포머 : 플레이어 점프하기

TXMAY·2023년 7월 24일
0

Unity 튜토리얼

목록 보기
16/33
post-thumbnail

이번 강좌는 플레이어 점프하기에 관한 강좌다.


물리 점프

Player 스크립트에 다음과 같은 코드를 추가한다.

...

public float jumpPower;
...

void Update()
{
    if (Input.GetButtonDown("Jump"))
    {
        rigid.AddForce(Vector2.up * jumpPower, ForceMode2D.Impulse);
    }
    ...
    
}

Inspector에서 Jump Power를 지정하고 스페이스바를 누르면 점프한다.
중력값을 바꾸면 떨어지는 속도가 바뀌는데 Rigidbody의 Gravity Scale을 바꿔도 되지만, 'Edit - Project Settings - Physics 2D - Gravity'의 값을 바꿔도 된다. (여기서 바꾸는 중력은 프로젝트 전체에 적용되고 오브젝트에 적용되는 중력은 Gravity * Gravity Scale이다)

애니메이션

이동과 같은 방식으로 점프 애니메이션을 추가한다.
다만 점프 애니메이션은 반복하게 될 때 애니메이션이 이상해지므로(떨어지는데 도약하는 모습이 된다) Loop Time을 비활성화한다.
점프는 어느 상황에서든(제자리, 이동) 할 수 있으므로 Transition을 두 애니메이션 다 연결해 준다.
isRunning 매개변수처럼 bool 타입의 isJumping 매개변수를 생성한다.
이동 -> 점프의 Conditions는 'isRunning - true, isJumping - true'로 설정하고(반대는 isJumping - false로), 제자리 -> 점프의 Conditions는 'isRunning - false, isJumping - true'로 설정한다(반대는 isJumping - false로).
그리고 Player 스크립트에 다음과 같은 코드를 추가한다.

...

void Update()
{
    if (Input.GetButtonDown("Jump"))
    {
        ...
        
        anim.SetBool("isJumping", true);
    }
    ...
    
}

실행하면 문제가 하나 있는데 점프 후 착지를 해도 애니메이션의 변화가 없다.

레이 캐스트

위 문제를 해결해 보겠다.
문제를 해결하기 위해 레이 캐스트(Ray Cast)를 사용하겠다.
Ray Cast : 오브젝트 검색을 위해 Ray를 쏘는 방식
Player 스크립트에 다음과 같은 코드를 추가한다.

...

void FixedUpdate()
{
    ...
    
    Debug.DrawRay(rigid.position, Vector3.down, new Color(0, 1, 0));
}
...

DrawRay() : 에디터 상에서만 Ray를 그려주는 함수
실행하면 Game에서는 아무것도 보이지 않지만, Scene에서는 Player 오브젝트에 아래 방향으로 초록색 선이 생긴 것을 볼 수 있다.
위 코드는 Ray를 보는 용도로만 사용한 코드고 실제 Ray를 사용해 보겠다.
위 코드 밑에 다음과 같은 코드를 추가한다.

...

void FixedUpdate()
{
    ...
    
	if (rayHit.collider != null)
    {
        Debug.Log(rayHit.collider.gameObject.name);
    }
}

...

RaycastHit : Ray에 닿은 오브젝트
RaycastHit 변수의 콜라이더로 검색 확인이 가능하다.
다만 Ray Cast는 Player의 위치에서 시작하기 때문에 실행하면 플레이어만 감지하게 된다.
그렇기에 LayerMask를 설정해야 한다.
LayerMask : 물리 효과를 구분하는 정숫값
오브젝트를 선택한 후, Inspector에서 Layer 옆에 Default 부분을 누르면 여러 가지가 나오는데 'Add Layer'를 눌러 'Platform'이라는 레이어를 만들어 바닥 오브젝트에 적용한다.
그리고 코드를 다음과 같이 수정한다.

...
void FixedUpdate()
{
    ...
    
    RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector3.down, 1, LayerMask.GetMask("Platform"));

    if (rayHit.collider != null)
    {
        if (rayHit.distance < 0.5f)
        {
            anim.SetBool("isJumping", false);
        }
    }
}
...

GetMask(name) : 레이어 이름에 해당하는 정숫값을 리턴하는 함수
다만 아직도 문제가 생기는데 점프하는 순간 Ray Cast가 바닥과 닿아 애니메이션이 제대로 재생되지 않는다.
그렇기에 아래로 내려오는 중일 때만 Ray Cast가 작동하도록 코드를 다음과 같이 수정한다.

...

void FixedUpdate()
{
    ...
    
    if (rigid.velocity.y < 0)
    {
    	...
    }
}
...

그러면 애니메이션이 정상적으로 재생되는 모습을 볼 수 있다.

무한 점프 막기

스페이스바를 계속 누르면 무한 점프가 된다.
이를 막기 위해 Player 스크립트에 다음과 같은 코드를 추가한다.

...

void Update()
{
    if (Input.GetButtonDown("Jump") && !anim.GetBool("isJumping"))
    {
        ...
    }
    ...
    
}

이제 무한 점프가 되지 않는다.


이전에는 오브젝트 간의 직접적인 충돌만 감지해서 실행하는 방법을 사용했었는데 유니티는 이런 식으로도 할 수 있는 것이 신기했다.

profile
게임 개발 공부하는 고양이

1개의 댓글

comment-user-thumbnail
2023년 7월 24일

공감하며 읽었습니다. 좋은 글 감사드립니다.

답글 달기