11. 유니티 2D 게임 제작 - 점프 구현
물리력을 이용한 점프
먼저 점프는 단발적인 입력에 속하기 때문에 Update 함수를 이용해 구현해야함
if (Input.GetButtonDown("Jump"))
{
rigid.AddForce(new Vector2(0, jumpPower), ForceMode2D.Impulse);
}
먼저 이동과 같은 방법으로 구현해봄
중력과 공기저항과 같은 문제로 인해 떨어지는 속도가 매우 느리게 떨어짐
첫번째 방법으로는 ProJect Setting 의 Physics에서 변경해서 가능
혹은 Rigidbody에서 Gravity Scale을 변경함으로써 가능
점프 애니메이션 적용
현재는 점프할때 그냥 공중으로 올라갈뿐이기 때문에 점프 애니메이션을 추가할 필요성이 생김
먼저 이전과 같이 애니메이터 편집
if (Input.GetButtonDown("Jump"))
{
if (isJump == false)
{
animator.SetBool("isJumping", true);
rigid.AddForce(new Vector2(0, jumpPower), ForceMode2D.Impulse);
isJump = true;
}
}
이후 점프를 다루는 if 문에
setBool을 이용해 애니메이션 재생시킴
하지만 이 코드를 이용하면 공중에서 무한으로 점프가 가능해지는 문제가 생김
이를 해결하기위해 레이캐스트 사용
레이캐스트
*RayCast : 오브젝트 검색을 위해 Ray를 쓰는 방식
Debug.DrawRay(rigid.position, Vector3.down, new Color(0, 1, 0));
먼저 코드를 입력해 레이가 그려지는것을 확인해봄
RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector2.down, 1);
if (rayHit.collider != null ) {
Debug.Log(rayHit.collider.name);
}
*RayCastHit : Ray에 닿은 오브젝트의 정보를 저장
레이를 쏘고 레이에 맞은 오브젝트의 정보를 불러옴
그러나 RayCastHit는 관통이 되지 않기 때문에 플레이어의 중심점으로부터 나온
Ray는 플레이어의 RigidBody에 맞기 떄문에 플레이어의 정보가 불러와지게 됨
*LayerMask : 물리효과를 구분하는 정수값
물리에서 필터와 같이 작용하는 Layer를 이용
tag는 string과 같이 간단한 식별자지만 Layer는 다른 레이어끼리 부딫히지 않게 설정할 수 있는 식별자
tag와 같은 방식으로 레이어를 새로 하나 작성
RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector2.down, 1, LayerMask.GetMask("Platform"));
*LayerMask.GetMask("레이어이름") : 특정 레이어에게만 레이가 부딫힐수 있게 함
이를 이용하면 레이가 특정 레이어에게만 반응해서 정보를 불러오는것을 볼 수 있음
if (rayHit.collider != null ) {
{
if(rayHit.distance < 0.5f)
{
Debug.Log(rayHit.collider.name);
}
}
}
.distance : Ray에 닿았을 때의 거리
distance를 이용하면 거리가 가까워지지않는다면 로그가 발생하지 않는것을 볼 수 있음
이를 이용해 점프 애니메이션 재생 코드 작성
RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector2.down, 1, LayerMask.GetMask("Platform"));
if (rayHit.collider != null ) {
{
if(rayHit.distance < 0.5f)
{
animator.SetBool("isJumping", false);
}
}
}
하지만 이대로 빌드하면
플레이어가 이미 바닥과 닿고 있는 상태에서 점프하기 때문에
위 코드가 상시 실행되어 isJumping가 항상 false상태가 되어있기에
점프 애니메이션이 아예 실행이 되지않음
if(rigid.velocity.y < 0)
{
RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector2.down, 1, LayerMask.GetMask("Platform"));
if (rayHit.collider != null)
{
{
if (rayHit.distance < 0.5f)
{
animator.SetBool("isJumping", false);
}
}
}
}
if 플레이어가 하강하고 있을 때(y축 속도가 0이하일 때) 라는 조건을 추가함으로써
하강을 하다 바닥과 가까워 졌을때만 isJumping이 false가 되어 idle 애니메이션으로 돌아가게 함
하지만 이경우에 아직 무한점프는 된다는 문제점이 있음
무한 점프 해결
//점프
if (Input.GetButtonDown("Jump") && !animator.GetBool("isJumping"))
{
animator.SetBool("isJumping", true);
rigid.AddForce(new Vector2(0, jumpPower), ForceMode2D.Impulse);
}
animator의 매개변수 상태도 if문의 조건으로 가져올 수 있음
*.GetBool : bool 매개변수의 값을 가져옴
정리
레이캐스트
가상의 빔을 쏴서 오브젝트를 검색하는 기능
RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector2.down, 1, LayerMask.GetMask("Platform"));
RaycastHit 변수를 이용해서 특정 레이어에 반응하는 방향이 정해진 ray를 발사할 수 있음
LayerMask.GetMask("레이어이름") : 특정 레이어에게만 레이가 부딫힐수 있게 함
레이캐스트변수.distance : Ray가 닿았을때의 거리
animator의 매개변수 상태도 불러올 수 있음