(유니티) 캐릭터 슬라이딩 구현하기

  • DKLaw 

경사로에서는 슬라이딩을 하면 멋지겠죠? 슈퍼마리오에서 마리오의 슬라이딩처럼 말이죠. 이렇게요.

캐릭터슬라이딩

1. 경사로 파악하기

경사로 타일을 별도의 레이어(저의 경우에는 “Ground”)로 지정한다음. 경사로를 레이캐스트 해서, 경사로의 각도를 구합니다.

	// 슬라이딩 할 수 있는지 경사도 판단하기 
	public bool SlopeDirection()
    {
		// Cast a ray straight down.
        hit = Physics2D.Raycast(transform.position, Vector2.down, 2f ,LayerMask.GetMask("Ground"));
		if (hit.collider != null)
		{
       		float currentSlope = Mathf.Round (Vector3.Angle (hit.normal, transform.up));
			if (currentSlope > 20 && m_Grounded) 
			{
				isInSlope = true;
				return true;
			}
		}

		isInSlope = false;
		return false;
    }

2. 경사로에서 플레이어 이동시키기

별도의 경사로 전용 무브 함수를 만들어서 경사로에서는 플레이어를 훨씬 빠르게 이동시키게 합니다.

	// 슬라이딩 : 경사로에서 캐릭터 움직이기 
	public void MoveSliding()
	{
		// Move the character by finding the target velocity
		Vector3 targetVelocity = new Vector2(hit.normal.x * 50f, m_Rigidbody2D.velocity.y - 10f);
		// And then smoothing it out and applying it to the character
		m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref m_Velocity, m_MovementSmoothing);
	}

3. 경사로에서 아래키를 누른 경우 경사로 전용 움직임 일어나게 하기

입력 컨트롤 소스 파일에는 다음과 같이 경사로로 파악된 경우, 아래방향키를 누르면 경사로 전용 움직이기를 실행하게 합니다.

        else if (controller.SlopeDirection() && bButtonEnable)  // 슬라이딩 입력 
        {
            if(Input.GetButton("Down") )
            {
                controller.SetPlayerState(6);
                controller.MoveSliding();
                IsInvincible = true;
            }  else if (Input.GetButtonUp("Down"))
            {
                controller.SetPlayerState(0);
                IsInvincible = false;
            }
        }else 

4. 참고

각 스테이트별 모션은 다음과 같이 정해줬습니다.

	// 애니메이션 상태 파악하기 
	private void VelocityState()   // 낙하 속도 및 좌우 속도에 따라 애니메이션 바꾸기 
    {
		if (state == State.climb)
		{
			if (AbsVertical > 0)
			{

			}else {
				if (Absspeed > Mathf.Epsilon  )
				{
					state = State.walk;
				}else {
					state = State.idle;
				}
			}
		
		}else if (state == State.crouch) 
		{
			// If the character has a ceiling preventing them from standing up, keep them crouching
			if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround))
			{
				state = State.crouch;
					
			}else if (isInSlope) 
			{
				
			}
			else	{
				if (Absspeed > Mathf.Epsilon  )
				{
					state = State.walk;
				}else {
					state = State.idle;
				}
			}
		}
		else   if(state == State.jump ) 
        {
            if(m_Rigidbody2D.velocity.y < 0.1f) 
            {
                state = State.falling;
            }
        }
       else if (state == State.falling) 
        {
            if(m_Grounded)
            {
                state = State.idle;
            }
        }else if (state == State.hurt)
        {

        }else if (Absspeed > 0.85) 
        {
            state = State.run;
        }
       else if (Absspeed > Mathf.Epsilon  )
        {
            state = State.walk;
        }else {
            state = State.idle;
        }
    }