본문 바로가기

내배켐 Unity TIL

Unity 28일차 TIL - Unity 팀 프로젝트 5 (RigidBody Material(Bounce))

Ball이 Paddle과 충돌될 때 법선 벡터를 이용해서 입사각 반사각을 구하는 게 아닌 Material의 Bounce 값을 이용해서 구현을 했었는데 문제가 있었다.

 

어느 순간  각도 변화 없이 무한 반복으로 횡 혹은 종 움직임이 있어가지고, 처음에는 왜 그런지 몰랐었는데 Debug를 찍어보니 무한 반복으로 이동하기 직전에 y 혹은 x 값이 normalized를 했을 때 기준으로 0.05 정도의 값이 나오면 충돌 이후에 y 혹은 x의 값이 0이 됐다.

 

정확한 이유는 모르겠지만 Collider에 충돌이 일어난 이후에 y 값과 x 값이 일정 값 이하가 되면 충돌된 이후에 방향이 0으로 변경이 되는구나 하고 생각했다.

 

그래서 Collider 충돌이 일어나기 직전에 값을 알면 값을 보정해서 넣어줄 수 있겠다고 생각을 해서 FixedUpdate를 사용해서 일단은 횡이 무한 반복하는 것을 막으려고 했다.

private void FixedUpdate
{
	Vector2 ballVelocity = rb2d.velocity;
    if (ballVelocity.magnitude != speed)
        rb2d.velocity = ballVelocity.normalized * speed;

    if (isHitTop)
    {
        if (rb2d.velocity.y == 0f && rb2d.velocity.x > 9f)
        {
            Vector2 nowVector = new Vector2(befordBallMovement.x - 0.5f, -befordBallMovement.y - 0.5f).normalized * speed;
            rb2d.velocity = nowVector;
        }
        else if (rb2d.velocity.y == 0f && rb2d.velocity.x < -9f)
        {
            Vector2 nowVector = new Vector2(befordBallMovement.x + 0.5f, -befordBallMovement.y - 0.5f).normalized * speed;
            rb2d.velocity = nowVector;
        }
        isHitSide = false;
    }

    if (isHitSide)
    {
        if (rb2d.velocity.y == 0f && rb2d.velocity.x > 9f)
        {
            if (befordBallMovement.y > 0f)
            {
                Vector2 nowVector = new Vector2(-befordBallMovement.x + 0.5f, befordBallMovement.y + 0.5f).normalized * speed;
                rb2d.velocity = nowVector;
            }
            else if (befordBallMovement.y < 0f)
            {
                Vector2 nowVector = new Vector2(-befordBallMovement.x + 0.5f, befordBallMovement.y - 0.5f).normalized * speed;
                rb2d.velocity = nowVector;
            }
        }
        else if (rb2d.velocity.y == 0f && rb2d.velocity.x < -9f)
        {
            if (befordBallMovement.y > 0f)
            {
                Vector2 nowVector = new Vector2(-befordBallMovement.x - 0.5f, befordBallMovement.y + 0.5f).normalized * speed;
                rb2d.velocity = nowVector;
            }
            else if (befordBallMovement.y < 0f)
            {
                Vector2 nowVector = new Vector2(-befordBallMovement.x - 0.5f, befordBallMovement.y - 0.5f).normalized * speed;
                rb2d.velocity = nowVector;
            }
        }
        isHitSide = false;
    }

    befordBallMovement = rb2d.velocity;
}

 

BallMovement Script에서 구현을 했고, 벽면을 Top과 Side 쪽에 Layer를 구분시켜줘서 OnColliderEnter2D에서 Layer가 Top이면 isHitTop = true로 Side면 isHitSide = true로 설정을 해주고 FixedUpdate에서 보정을 해줬다.

 

이렇게 한 이유는 처음에는 들어오기 직전에 vector2 값을 알고 있으면 충돌이 난 이후에 vector2의 y 값이 0이 됐을 때 직전에 y 값 대로 새로 생성을 해주면 문제가 없겠다고 생각을 했었는데 왜인지는 아직 모르겠지만 그렇게 해줬음에도 불구하고 y 값이 0으로 바뀌게 됐다. 그래서 충돌이 난 이후에 velocity의 vector 값을 변경해 줘도 y 값이 일정 값 이하면은 0으로 바뀌는 건가라는 생각이 들어서 그냥 y 값과 x 값을 일정 값 이상으로 조정을 해줬다.

근데 지금 작성하면서 생각해보니 y 값만 수정해줘도 됐을 것 같다.

 

Top과 Side를 나눠서 구분한 이유는 검은색이 들어올 때 Vector2, 빨간색이 나갈 때 Vecotr2다.

각각 2가지 경우지만 그 경우가 다르기도 했고, 사실 시간이 없었다.

최대한 빠르게 해결을 해야 해서 생각할 시간보다는 그냥 바로 생각나는 대로 코딩했던 것 같다.

 

그래서 검은색 vector2가 들어오고 나서 빨간색 vector2가 나갈 때 vector2의 y 값이 0이 되면 검은색 vector2의 값에서 빨간색 vector2의 방향으로 갈 수 있게끔 x와 y를 상황에 맞게 반전시켜주고, 일정 값 이상을 보정시켜줬다.