private void SlopeCheck()
{
RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, detectDistance, groundCheckLayer);
RaycastHit2D frontHit = Physics2D.Raycast(frontChecker.position, frontChecker.right * transform.localScale.x, 0.1f, groundCheckLayer);
if (DebugMode)
{
Debug.DrawLine(frontChecker.position, frontChecker.position + frontChecker.right * transform.localScale.x, Color.blue);
Debug.DrawLine(hit.point, hit.point + perp, Color.red);
Debug.DrawLine(hit.point, hit.point + hit.normal, Color.blue);
}
if (hit || frontHit)
{
if (frontHit)
hit = frontHit;
}
perp = Vector2.Perpendicular(hit.normal).normalized;
slopeAngle = Vector2.Angle(hit.normal, Vector2.up);
isSlope = (slopeAngle > 10) ? true:false; // 조건을 ==0 으로 설정시 정밀도가 떨어짐
}

플레이어의 아래와 그 살짝 앞방향으로 Raycast 해서 수직 벡터를 구함.

if (isSlope && isGround && slopeAngle < maxAngle)
{
rigid.velocity = moveDir.x * perp * -1 * moveSpeed;
}
경사면일 때는 그 수직 벡터 만큼 곱해준 방향으로 이동 시켜줌.
상태패턴으로 분리하고나서는 RunState에서 다음과 같이 진행함, SlopeCheck는 바닥에 있을때만.
public override void Update()
{
SlopeCheck();
}
public override void FixedUpdate()
{
if (!player.isSlope)
{
if (player.moveDir.x < 0 && player.rigid.velocity.x > -player.maxSpeed)
{
player.rigid.velocity = new Vector2(-player.moveSpeed, player.rigid.velocity.y);
effect.isFlip = true;
}
else if (player.moveDir.x > 0 && player.rigid.velocity.x < player.maxSpeed)
{
player.rigid.velocity = new Vector2(player.moveSpeed, player.rigid.velocity.y);
effect.isFlip = false;
}
}
else
{
player.rigid.velocity = player.moveDir.x * perp * -1 * player.moveSpeed;
}
}
private void SlopeCheck()
{
RaycastHit2D hit = Physics2D.Raycast(player.transform.position, Vector2.down, 1f, player.groundCheckLayer);
RaycastHit2D frontHit = Physics2D.Raycast(player.frontChecker.position, player.frontChecker.right * player.transform.localScale.x, 0.1f, player.groundCheckLayer);
if (player.DebugMode)
{
Debug.DrawLine(player.frontChecker.position, player.frontChecker.position + player.frontChecker.right * player.transform.localScale.x, Color.blue);
Debug.DrawLine(hit.point, hit.point + perp, Color.red);
Debug.DrawLine(hit.point, hit.point + hit.normal, Color.blue);
}
if (hit || frontHit)
{
if (frontHit)
hit = frontHit;
}
perp = Vector2.Perpendicular(hit.normal).normalized;
slopeAngle = Vector2.Angle(hit.normal, Vector2.up);
player.isSlope = (slopeAngle > 10) ? true : false;
}
