Unity/Study

유니티 2D 공 충돌 물리엔진

홍삼맛 2023. 11. 30. 18:55

2D 공 충돌 물리엔진

'알카노이드' 스타일의 공 충돌 물리엔진을 구현하려 한다.


기능 소개

화면 충돌

화면 충돌 구성

  • 화면을 덮는 Edge Collider 2D를 생성
  • 바닥은 다른 Box Collider 2D로 충돌 시, 공을 파괴시키는 기능을 추후에 넣을 예정 

Ball Bound Screen

public static class Extensions
{
    /// 카메라 사이즈에 맞는 엣지 콜라이더 바운드 생성
    public static void GenerateCameraBounds(this EdgeCollider2D screenEdge)
    {
        var halfScreenHeight = Camera.main.orthographicSize;
        var halfScreenWidth = Camera.main.orthographicSize * Screen.width / Screen.height;
        
        var bounds = new Vector2[4];
        bounds[0] = new Vector2(-halfScreenWidth, -halfScreenHeight);
        bounds[1] = new Vector2(-halfScreenWidth, halfScreenHeight);
        bounds[2] = new Vector2(halfScreenWidth, halfScreenHeight);
        bounds[3] = new Vector2(halfScreenWidth, -halfScreenHeight);

        screenEdge.points = bounds;
    }
}
  • 메인 카메라 사이즈를 기준으로 좌표값을 불러 왼쪽부터 순서대로 포인터를 잡아준다.

공 물리엔진

공 물리엔진 컴포넌트 설정

  • 움직일 공의 필수 컴포넌트 2개인 Rigidbody2D와 CircleCollider2D를 추가
  • 움직임을 제어할 스크립트로 시작 속도와 최대 속도값을 지정

Physics Material 2D

  • 물리 머티리얼 2D를 생성해 공의 머터리얼 값에 부여
  • 값 설정은 Friction = 0, Bounciness = 1을 주어 운동에너지값이 손실없이 무한으로 팅겨지도로 만든다.

ArkanoidBall.cs

public class ArkanoidBall : MonoBehaviour
{
    [Header("Speed")]
    [SerializeField] public float ballStartSpeed;
    [SerializeField] public float ballMaxSpeed;

    private Rigidbody2D ballBody;

    private void Awake()
    {
        ballBody = GetComponent<Rigidbody2D>();
    }

    private void FixedUpdate()
    {
        MoveBall();
    }

    public void StartBall()
    {
        ballBody.velocity = new Vector2(0, ballStartSpeed);
    }

    private void MoveBall()
    {
        if (ballBody.velocity.magnitude > ballMaxSpeed)
        {
            ballBody.velocity = ballBody.velocity.normalized * ballMaxSpeed;
        }
    }
}
  • 스크립트로 시작 속도와 최대 속도를 조정한다
  • 시작 발사는 수직으로 발사하게 매서드를 만들고, 최대 속도를 안넘어가게 FixedUpdate로 계속 체크해준다.

구현 결과