Rigidbody2D 컴포넌트
- 2차원 공간에서 오브젝트의 물리와 중력을 담당하는 컴포넌트

- 오브젝트의 질량, 위치 움직임에 대한 마찰력, 회전 움직임에 대한 마찰력, 오브젝트 중력 계수, 원하는 축만 외부로부터 받은 물리력에 의해 이동/회전하지 않도록 설정 가능

Collider2D 컴포넌트
- 2차원 공간에서 오브젝트의 충돌 범위를 나타내는 컴포넌트
- 충돌 범위나 생김새나 특징에 따라 "OO Collider 2D"와 같이 이름을 명명함
- Box, Circle, Edge, Polygon, Capsule, Composite

Box Collider 2D
- Box Collider2D 컴포넌트는 사각형 형태의 충돌 범위를 설정할 때 사용

- 충돌 범위의 중심점 위치 Offset과 충돌 범위의 크기 Size 파라미터로 충돌 범위를 설정
- 그림에 보이는 것과 같이 모든 충돌 범위는 화면에 보이는 이미지와 동일하게 설정할 수도 있지만 더 크거나 작게 설정할 수도 있다.
Circle Collider 2D
- Circle Collider2D 컴포넌트는 원 형태의 충돌 범위를 설정할 때 사용
- 원 충돌이 모든 충돌 중 연산 속도가 가장 빠름

- 충돌 범위의 중심점 위치 Offset과 충돌 범위의 반지름 Radius 파라미터로 충돌 범위를 설정
Edge Collider 2D
- EdgeCollider2D 컴포넌트는 선 형태의 충돌 범위를 설정할 때 사용
- 충돌 범위의 중심점 위치 Offset과 선의 두께 Edge Radius, 선을 이루는 점의 개수와 각 점의 위치 Points 배열 파라미터로 충돌 범위를 설정
- 주로 2D 게임에서 바닥 충돌 제어에 많이 사용

Polygon Collider 2D
- 2D Sprite의 생김새와 동일한 충돌 범위를 설정할 때 사용
- 세밀한 충돌이 가능하지만 그만큼 충돌을 검사하는 연산량이 늘어나기 때문에 Points 정보를 수정해 사용하는 것을 권장
- 충돌 범위의 중심점 위치 Offset과 충돌 범위를 표현하는 점 정보 Points 파라미터로 충돌 범위를 설정

Capsule Collider 2D
- 위아래가 둥근 캡슐 형태의 충돌 범위를 설정할 때 사용
- 충돌 범위의 중심점 위치 Offset과 충돌 범위의 크기 Size, 둥근 캡슐의 방향 Direction 파라미터로 충돌 범위를 설정
- 주로 플레이어, 적과 같은 캐릭터의 충돌에 활용

Composite Collider 2D
- 여러 오브젝트의 충돌 범위를 하나의 충돌 범위로 묶어주는 역할

- CompositeCollider2D 컴포넌트는 하나로 묶기 때문에 충돌 범위 사이에 생길 수 있는 균열에 빠지지 않도록 방지하고, 연산량을 줄여 최적화에 도움을 준다
- 다만 모든 충돌 컴포넌트를 다 묶을 수 있는 것은 아니고 BoxCollider2D와 PolygoneCollider2D 컴포넌트만 묶을 수 있다


- CompositeCollider2D 컴포넌트는 충돌 범위를 묶어주는 역할만하기 때문에 일반적으로 빈 오브젝트를 생성해 CompositeCollider2D 컴포넌트룰 추가한다.

- 이 때 Rigidbody2D 컴포넌트가 함께 추가되는데 중력을 사용하지 않는다면 GravityScale을 0으로 설정

- 하나로 묶고 싶은 충돌 오브젝트들을 CompositCollider2D 오브젝트의 자식으로 설정하고, Collider2D 컴포넌트에 있는 Used By Composite를 true로 설정 (체크)


게임 오브젝트 충돌 처리
서로 다른 두 오브젝트의 충돌 조건
- 서로 다른 두 오브젝트가 충돌하기 위한 필수 조건
- 두 오브젝트 모두 충돌 범위인 Collider2D 컴포넌트를 가지고 있어야 한다
- 둘 중 하나 이상의 오브젝트가 물리 처리를 담당하는 Rigidbody2D 컴포넌트를 가지고 있어야 한다.

- 유니티는 2D/3D 게임 제작을 위해 Rigidbody2D, Collider2D는 2D 게임 제작용
- Rigidbody, Collider는 3D 게임 제작용으로 제공
- Collider2D와 Collider의 충돌 / Rigidbody로 Collider2D의 충돌 검사와 같이 서로 다른 차원의 컴포넌트들은 반응하지 않기 때문에 통일해서 사용해야한다.
- Player 오브젝트의 충돌 처리를 위해 Rigdbody2D와 CapsuleCollider2D 컴포넌트 추가
- 중력의 영향을 받지 않도록 Rigdbody2D 컴포넌트의 GravityScale은 0으로 설정하고 츙돌했을 때 충돌 힘에 의해 회전하지 않도록 Constraints.Freeze Rotation z를 true (체크)로 설정

- CapsuleCollider2D 커ㅏㅁ포넌트의 Offset은 (0, 0), Size는 (1, 2)로 설정

- 플레이와 충돌하는 벽 오브젝트를 4개 생성
- 벽오브젝트의 충돌 처리를 위해 BoxCollider2D 컴포넌트를 추가하고 벽의 위치와 크기를 설정

- 이 상태에서 게임을 실행하면 장애물 충돌에 대한 처리가 없기 때문에 transform.position으로 이동하고, 벽과의 충돌 처리로 밀려나가는 과정을 반복해 벽과 충돌했을 때 벽 방향으로 방향키를 누르고 있으면 플레이어가 덜덜 거린다.

Rigidbody2D 컴포넌트를 이용한 오브젝트 이동
- transform.position 변수 값을 설정해 위치를 제어하는 것 대신 rigidbody2D 컴포넌트에 있는 velocity 속력 변수를 설정해 오브젝트를 이동하도록 한다.

- transform 컴포넌트를 제외한 다른 컴포넌트에 접근할 때는 GetComponent<컴포넌트>()과 같이 접근해서 사용
1. 컴포넌트 정보를 저장할 변수 선언
private Rigidbody2D rigid2D;
2. GetComponent<>()로 불러온 컴포넌트 정보를 변수에 저장
rigid2D = GetComponent<Rigidbody2D>();
3. 컴포넌트 정보가 저장되어 있는 변수를 이용해 컴포넌트의 메소드, 프로퍼티, 변수 제어
rigid2D.velocity = Vector2.right * 5;
- 일반적으로 제어하려고 하는 컴포넌트와 동일한 타입의 변수를 선언하고 변수에 GetComponent<>()로 불러온 컴포넌트 정보를 담아둔 후 컴포넌트에 접근해 파라미터 값을 수정하거나 메소드를 실행
모든 이동은 Transform 컴포넌트를 설정하는 것으로 물리, 중력, 장애물에 대한 처리와 같은 것들을 실제 이동을 하는 "tansform.position += .." 코드 전에 작성해야한다. 우리가 이 코드를 직접 작성하려면 많은 시간이 들기 때문에 유니티에서 제공하는 Rigidbody2D 컴포넌트를 사용한다.
Rigidbody2D 컴포넌트의 속력(velocity) 변수 값만 설정하면 Rigidbody2D 가 오브젝트를 이동시켜준다
※ 속력을 설정할 때는 Time.deltaTime을 곱하지 않는다
- Rigidbody2D 스크립트 내부에서 매 프레임 이동 메소드가 실행되고 있지만 속력 (velocity)의 기본 값이 (0, 0)이기 때문에 이동하지 않는다

- Rigidbody2D 타입의 변수를 선언하고, Awake() 메소드에서 rigid2D 변수에 GetComponent Rigidbody2D();로 컴포넌트 정보를 얻어와 저장한다.

- rigid2D.velocity = moveDirection * moveSpeed; 와 같이 속력 값을 설정하면 매 초 moveDirection 방향으로 moveSpeed 거리만큼 이동

- 게임을 실행했을 때 이제 벽에 부딪혀도 더 이상 해당 방향으로 이동하려고 하지 않고 멈춰 있는 것을 볼 수 있다.
충돌 이벤트 메소드
- 유니티는 오브젝트가 충돌했을 때 단순히 두 오브젝트의 물리적 충돌 처리뿐만 아니라 개발자가 원하는 추가 동작을 처리할 수 있도록 충돌 이벤트 메소드를 제공
OnCollision2D와 OnTrigger2D
- OnCollision2D는 물리적인 충돌도 일어나면서 충돌 상황에 따라 특정 메소드를 호출하고 싶을 때 사용
- OnTrigger2D는 물리적인 충돌 없이 특정 메소드만 호출하고 싶을 때 사용
- 주로 아이템 획득이나 트랩과 같은 발판을 밟는 상황에 사용
- 각각 Enter, Stay, Exit 세 종류의 메소드가 존재하며, 매개변수는 메소드를 호출하는 대상에게 부딪힌 게임 오브젝트의 충돌 정보

물리적인 충돌과 충돌 이벤트 메소드 호출
[SerializeField] 어트리뷰트
변수의 은닉성을 위해 private으로 변수를 선언했을 때 외부 클래스에서 접근이 불가능하고, 유니티 에디터의 Inspector View에도 노출되지 않는다. 선언하는 변수 앞에 [SerializeField] 어트리뷰트를 작성하면 코드 접근은 불가능하게 유지되고, Inspector view에서 값능ㄹ 제어할 수 있도록 노출이 된다.

- Inspector View에서 수정이 가능하도록 [SerializeField] 어트리뷰트를 작성하고, Color 타입의 변수 myColor를 선언
- Awake() 메소드에서 SpriteRender 컴포넌트 정보를 저장

- 충돌이 일어나는 순간 1회 호출되는 OnCollisionEnter2D() 메소드에서 spriteRenderer.color = myColor; 로 벽의 색상을 myColor로 변경

- 충돌이 유지되는 동안 매 프레임 호출되는 OnCollisionStay2D() 메소드에서 Debug.Log()로 Console.View에 텍스트를 출력

- 충돌이 종료되는 순간 1회 호출되는 OnCollisionExit2D() 메소드에서 spriteRenderer.color = Color.white;로 벽의 색상을 하얀색으로 변경

- 작성이 완료된 스크립트를 벽 오브젝트에 컴포넌트 적용

- 벽 오브젝트를 선택하고 Insepctor View를 보면 OnCollision2DSample 컴포넌트에 MyColor 변수가 보이고, 색상표를 선택하면 RGBA의 색상을 설정할 수 있다.

- 이 때 주의할 점은 유니티의 색상 변수는 (0, 0, 0, 0)이 기본 값으로 RGB 색상만 설정하고 알파(A) 값을 설정하지 않아 충돌했을 때 벽이 사라지는 현상을 볼 수 있다.

- 반드시 Alpha 값을 255(최대)로 RGBA 모두 설정해야 한다.


- 게임을 실행하면 네 방향의 벽과 충돌했을 때 충돌이 시작되는 순간 벽의 색상이 MyColor 색상으로 바뀌고 충돌하고 있는 동안 ConsoleView에 "오브젝트 이름 : OnCollsionStay2D() 메소드 실행" 텍스트가 출력
- 충돌이 종료되는 순간 벽의 색상이 원래 색상인 하얀색(Color.white)으로 바뀌게 된다.
물리적인 충돌 없이 충돌 이벤트 메소드 호출

- 플레이어가 특정 오브젝트와 충돌했을 때 이동하는 오브젝트를 사용하기 위해 2D Capsule 오브젝트를 생성하고, 이름을 Mover로 변경 ([GameObject - 2D Object - Sprites - Capsule])

- Mover 오브젝트의 위치는 (0, 2.5, 0), 크기는 (0.4, 0.4, 0.4)로 설정

- 왼쪽 이동 트리거 오브젝트를 사용하기 위해 2D Circle 오브젝트를 생성하고, 이름을 LeftMoveTrigger로 변경 ([GameObject - 2D Object - Sprites - Circle])
- 오브젝트의 위치는 (-3, -3, 0)으로 설정하고, 충돌 처리를 위해 CircleCollider2D 컴포넌트를 추가한 후 CircleCollider2D 컴포넌트의 IsTrigger 변수를 true로 설정한다

- Ctrl + D 로 오브젝트를 복제한 후 이름을 RightMoveTrigger 오브젝트로 설정 위치를 (3, -3, 0)으로 설정

- 오브젝트가 충돌했을 때 물리적인 충돌 없이 이벤트 메소드를 호출하는 OnTrigger2DSample 스크립트 생성
- 이 스크립트는 오브젝트가 직접 이동하는 것이 아닌 이동 시킬 별도의 오브젝트를 설정

- 이동 시킬 오브젝트 moveObject 변수와 이동 방향 moveDirection, 이동 속도 moveSpeed 변수 선언
- Inspector View에서 설정할 수 있도록 [SerializeField] 어트리뷰트를 작성한다.

- 충돌이 일어나는 순간 1회 호출되는 OnTriggerEnter2D() 메소드에서 moveObject.GetComponent SpriteRenderer ().color = Color.black; 으로 moveObject 변수에 등록되어 있는 오브젝트이 색상을 검은색으로 변경

- 충돌이 유지되는 동안 매 프레임 호출되는 OnTriggerStay2D() 메소드에서 moveObject.position += moveDirection moveSpeed TimedeltaTime; 으로 moveObject 변수에 등록되어 있는 오브젝트를 moveDirection 방향, moveSpeed 속도로 이동

- 충돌이 종료되는 순간 1회 호출되는 OnTirggerExit2D() 메소드에서 moveObject.GetComponent SpriteRenderer ().color = Color.white; 로 moveObject 변수에 등록되어 있는 오브젝트의 색상을 하얀색으로 변경하고 moveObject.position = new Vector3(0, 2.5f, 0)으로 moveObject 변수에 등록되어 있는 오브젝트의 위치를 (0, 2.5, 0)으로 설정

- 작성이 완료된 OnTrigger2DSample 스크립트를 LeftMoveTrigger, RightMoveTrigger 오브젝트에 컴포넌트로 적용
- MoveTrigger 오브젝트와 플레이어가 충돌하면 MoveTrigger 오브젝트가 아닌 OnTrigger2DSample 컴포넌트의 MoveObject 변수에 등록하는 오브젝트가 이동하게 된다.



- MoveObject 변수에 Mover 오브젝트를 등록하고 MoveSpeed는 3으로 설정한 후 LeftMoveTrigger 오브젝트의 MoveDiretion은 (-1, 0, 0), RightMoveTrigger 오브젝트의 MoveDirection은 (1, 0, 0)으로 설정


- 각 트리거에 닿을 경우 Mover가 왼쪽 혹은 오른쪽으로 이동하게 된다. 충돌이 종료되면 원래 위치로 돌아간다
- 충돌이 유지되고 있지만 둘 다 움직임이 없는 경우에는 OnXXStay2D() 메소드가 1초 정도 호출되고 멈춘다