유니티 리지드바디 충돌 - yuniti lijideubadi chungdol

충돌 처리

충돌 처리는 게임 상에서 어떠한 일이 발생 되는 것을 감지를 할 수 있어야 한다.

게임에서의 충돌은 특정 영역에 진입했을 때나 두 물체 간의 충돌, 마우스 픽킹, UI버튼을 누르는 등의

이벤트 처리도 모두 충돌의 개념이다. 물리 충돌을 구현할 때는 FixedUpdate()에서 구현한다.

ex) 몬스터가 서있는 위치를 충돌로 찾는다.

렌더링시스템과 물리시스템

유니티 시스템의 큰 특징은 렌더링 시스템과 물리시스템이 구분되어져 있다.

Update()와 FixedUpdate() 갱신 주기가 다르기 때문에 호출 속도가 다르다.

Update()

Update() 메소드는 매프레임마다 호출되며, 렌더링을 다루는 시스템이다.

FixedUpdate()

물리량을 다루는 시스템으로, 물리 충돌을 구현할 때는 FixedUpdate()에서 구현한다.

FixedUpdate에서는 Time.fixedDeltaTime로 시간 클래스를 사용한다.

충돌 검사 방법

충돌 처리를 하기 위해서는 Rigidbody와 Collider컴포넌트가 필요하다.

콜라이더 컴포넌트는 충돌체 구현, Rigidbody 컴포넌트는 물리 구현이다.

게임오브젝트에는 콜라이더 컴포넌트가 적용되어 있어야 하며,

콜라이더에 물리를 적용하고 충돌 처리를 할 수 있는 것이 리지드바디 컴포넌트이다.

충돌 처리를 할 게임오브젝트는 이 두 가지가 꼭 붙어야 한다.

Rigidbody 컴포넌트

물리를 구현하기 위해 반드시 필요한 컴포넌트로 게임오브젝트에 적용시 중력이 적용된다.

// 물리 : 시공간에서의 물체의 운동, 에너지 힘을 말한다.

리지드 바디 컴포넌트가 추가되면 물리학의 통제로 게임오브젝트는 중력의 영향을 받는다.

충돌 이벤트를 사용해 충돌 처리를 하기 위해선 게임오브젝트 중에서 최소 하나의 게임오브젝트는 리지드바디 컴포넌트를 가지고 있어야 한다.

프로퍼티

Mass : 질량

Drag : 저항력, 움직임 방향에 대하여 반대로 작용한다.

Anqular Drag : 회전에 대한 저항력 의미

Use Gravity : 중력을 사용할지 여부

Is Kinematic : 물리 효과 적용 여부

Interpolate : Update() 메소드와 FixedUpdate() 메소드가 독립적으로 움직일 경우이를 보완하기 위하여 렌더링 프레임의 위치로 물리의 결과를 보간하는 기능을 제공한다. 끊겨 보일 수 있는 단점이 있다. 

Collision Detection (충돌 감지)

Disrete : 충돌 이산 감지로 물리 프레임간 간격을 두고 충돌 감지를 하기 때문에 계산량이 적을 때 일반적으로 많이 사용한다.

Continuos : 충돌 연속 감지로 충돌이 일어날 것을 미리 예측하고 탐지한다. 정확하지만 계산량이 많다.

Constraints : 해당 좌표는 물리가 적용되지 않는다. 그러나 트랜스폼 컴포넌트의 위치나 회전에 새로운 값을 할당하여 위치나 회전을 변경하는 것은 막을 수 없다.

docs.unity3d.com/Manual/class-Rigidbody.html

Unity - Manual: Rigidbody

Rigidbody Switch to Scripting Rigidbodies enable your GameObjectsThe fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to i

docs.unity3d.com

Rigidbody컴포넌트의 주요 메소드

AddForce()

관성을 누적해서 속력을 증가 시킨다. 벡터의 크기와 방향이 적용되어 이동하게 된다.

발사체의 힘은 발사될 때 한번만 적용하면 된다.

force : 벡터값

mode : ForceMode : 관성 적용 방법

ForceMode에 따라서 힘이 적용되는 방법이 달라진다.

ex) 발사체 구현하기

특정 방향으로 향하는 게임오브젝트 물리량을 이용하여 발사체를 구현이 가능하다.

중력이 적용되어 수직으로 힘이 적용되어 포물선으로 전달된다.

// 매개변수 : 관성의 벡터값 전달, 관성 타입 전달 public void AddForce(Vector3 force, ForceMode mode = ForceMode.Force);

Rigidbody컴포넌트의 주요 프로퍼티

velocity

이전 속도를 리셋해서 관성을 무시하고 속도가 즉시 변경되고 새로운 속도를 사용한다. 

리지드바디의 velocity 변수로 현재 속도를 반환하고, 변경할 수 있다.

public Vector3 velocity;

docs.unity3d.com/ScriptReference/Rigidbody.html

Unity - Scripting API: Rigidbody

Adding a Rigidbody component to an object will put its motion under the control of Unity's physics engine. Even without adding any code, a Rigidbody object will be pulled downward by gravity and will react to collisions with incoming objects if the right C

docs.unity3d.com

충돌 처리 예외 사항

프레임드랍에 의한 충돌 무시 처리 방법

서버 기반일 경우 서버에서 판정한다.

프레임 드랍시에 대비한 처리는 예측을 통한 이전 위치로 이동 또는 판정하는 방법이 있다.

ex) 직선 상의 한 점이 위치해 있는가? (수학적으로 따진다.)

ex) 적을 총알로 맞춰야 하는데 총알이 너무 빠르면 텔레포트되서 통과해버릴 경우 처리 방법

물리기반 업데이트에서 물리충돌 구현시 발생할 가능성이 높다.

일단 유니티 기반 시스템 이해해야 한다.

총알 속도가 빨라서 충돌을 무시할 정도라면 시스템의 성능을 넘어선 것으로 기획을 조정해야 한다.

콜라이더(Collider)

콜라이더는 충돌 처리를 하기 위해 충돌을 감지하는 컴포넌트이다.

물체의 물리를 적용하거나 다른 물체와 충돌을 감지한다.

콜라이더 종류

3D Collider이며 2D일 경우에는 콜라이더 컴포넌트 이름에 2D가 추가 된다.

에셋에서 다운받은 캐릭터 게임오브젝트가 메시콜라이더 컴포넌트일 경우 무겁기 때문에 삭제하고 박스콜라이더 컴포넌트 추가하기

Box Collider : 유니티 기본 콜라이더이다. 게임오브젝트 생성시 게임오브젝트의 크기에 맞춰 기본적으로 셋팅되어 있다.

Sphere Collider : 연산속도가 빠른 대신에 인간형 같은 모델에는 적합하지 않다.

Capsule Collider : 인간형과 같은 모델에 적합하다.

Mesh Collider : 메시 형태로 콜라이더를 만들 수 있다. 그러나 메시가 복잡할 경우 계산량이 많아지기 때문에 게임속도에 영향을 주며, 설정에도 제약이 따른다. Mesh Collider가 제일 많이 사용된다.

docs.unity3d.com/Manual/CollidersOverview.html

Unity - Manual: Colliders

Colliders Collider components define the shape of a GameObjectThe fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to it.

docs.unity3d.com

부모 - 자식 게임오브젝트의 콜라이더 컴포넌트 관리 방법

부모 오브젝트에 자식 오브젝트인 Mesh 오브젝트는 별개의 게임오브젝트이다.

부모 오브젝트에 스크립트 컴포넌트와 콜라이더 컴포넌트를 추가하는 것이 좋다.

왜냐하면 Mesh 오브젝트에서 충돌이 일어날 경우 자식들을 전부 검사해서 부모와 비교해야 하기 때문에

에디터에서 콜라이더 컴포넌트는 스크립트 컴포넌트와 같이 부모 오브젝트에 추가해서 관리하도록 한다.

다른 게임오브젝트 모델에도 이 규칙을 설정해줘야 컴포넌트 관계가 꼬이지 않는다.

Q. 게임오브젝트 콜라이더 수정이유는 무엇이며 왜 콜라이더위치를 정하는 가?

>>Mesh 게임오브젝트에 붙일 경우 충돌은 되지만 그 오브젝트에는 해당 충돌 이벤트 메소드가 없고 부모오젝트에 스크립트가 있을 경우 적용이 되지 않는다. 그리고 최상위 오브젝트의 태그를 바꾼다고 하위 오브젝트 태그가 바뀌진 않기 때문이다.

부분 충돌 구현 시 콜라이더 컴포넌트 사용 방법

부분 충돌을 구현하려면 콜라이더박스를 여러 개 넣어야 한다. 팔 다리 몸통 머리에 각각 콜라이더를 붙여서 충돌을 정교하게 하고 싶은 경우에는 콜라이더 위치가 자식에 붙어야 하는 경우가 있다.

보통 콜라이더가 여러 개 붙어있는 것을 검색하려면 유연하게 만들어야 함.
콜라이더가 부모 위에만 있으란 법이 없고 두단계 한단계 위로 올수도 있다. 
또한 계층구조를 바꿀 수도 있다. 
이럴때는 재귀호출을 이용하여 위에서부터 아래로 훑는다. 

* Script reference GameObject.Find 검색해서 부모와 자식 오브젝트 관계 예시 참고하기그러나 연산량이 발생하기 때문에 우리는 콜라이더박스의 위치를 어디에 넣을 것인지 규칙을 정하는 것이다.

그래야 모델구조가 맞고 동일한 코드에서 재사용이 가능하다.

ex) 빨간거북이 콜라이더는 Mesh 오브젝트에 붙어 있는데 트롤은 최상위 부모에 콜라이더 붙어 있다. 삭제 후 빨간거북이오브젝트에 박스콜라이더를 새로 생성한다.

콜라이더 충돌 설정 방법

Collider > IsTrigger : 트리거 충돌 준비 완료

IsTrigger를 체크하지 않는다면 Collision 충돌로 인식하여 Trigger 관련 메소드가 아닌 Collision 관련 메소드 사용

충돌 이벤트 메소드

충돌했을 때 어떤 처리를 실행할지 결정하는 메소드이다. 

충돌한 게임오브젝트와 추가된 컴포넌트들은 충돌 처리 메소드를 실행한다.

충돌 종류에 따라 충돌 이벤트 메서드 중 알맞은 것을 선택하여 구현하다.

충돌은 크게 Collision과 Trigger로 구분

물리량이 적용된 충돌시 발생하는 충돌 메소드

일반 콜라이더를 가진 두 게임 오브젝트가 충돌할 때 실행된다.

충돌이 발생했을 경우 물리량이 적용된다.

질량이 적용되어 현상이 발생한다.

ex) 무거운 것보다 가벼운 것이 충돌하면 더 멀리 튕긴다.

Collision 관련 메소드

물리량이 적용되는 충돌 컴포넌트이다.

매개변수로 Collision (충돌)을 전달한다.

docs.unity3d.com/ScriptReference/Collision.html

Unity - Scripting API: Collision

Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close

docs.unity3d.com

OnCollisionEnter(Collider collision) : 충돌이 시작될 때 호출

OnCollisionStay(Collider collsion) : 충돌이 진행될 때 호출

OnCollisionExit(Collider collision) : 충돌이 종료될 때 호출

ex)

private void OnCollisionEnter(Conllision collsion) { Debug.Log(collision.gameObject.name + " : 충돌 시작"); } private void OnCollisionStay(Collision collision) { Debug.Log(collision.gameObject.name + " : 충돌 중"); } private void OnCollisionExit(Collision collision) { Debug.Log(collision.gameObject.name + " : 충돌 종료"); }

물리량이 적용되지 않은 충돌시 발생하는 충돌 메소드

트리거 충돌로 충돌한 두 게임오브젝트 중 하나라도 트리거 콜라이더라면 실행된다.

이 경우 두 게임오브젝트가 충돌했을 때 서로 통과하게 된다.

특정영역에 진입했을 경우나 포털영역에 진입했을 경우에 자주 사용 된다.

ex) 엘리베이터 앞에 서있을 때 엘리베이터가 움직인다.

Trigger 관련 메소드

매개변수로 Collider (충돌체)을 전달한다.

물리량이 적용되지 않는 충돌, 아이템 획득시 적용이 가능하다.

OnTriggerEnter(Collider other) : 트리거가 시작될 때 호출

OnTriggerStay(Collider other) : 트리거가 진행될 때 호출

OnTriggerExit(Collider other) : 트리거가 종료될 때 호출

ex)

private void OnTriggerEnter(Collider other) { Debug.Log("Trigger Enter :" + other.name); } private void OnTriggerStay(Collider other) { Debug.Log("Trigger Stay : " + other.name); } private void OnTriggerExit(Collider other) { Debug.Log("Trigger Exit : " + other.name); }

ex) OnTriggerEnter()

other의 게임오브젝트에 PlayerController 컴포넌트가 없으면 playerController에 null이 할당된다.이렇게 실수를 대비하여 코드를 만드는 것이 좋다.

private void OnTriggerEnter(Collider other) { //충돌한 상대방 게임오브젝트가 Player 태그를 가진 경우 if(other.tag == "Player") { //상대방 게임오브젝트에서 PlayerController 컴포넌트 가져오기 PlayerController playerController = other.GetComponent<PlayerController>(); //상대방으로부터 PlayerController 컴포넌트를 가져오는 데 성공했다면 if(playerController != null) { //상대방 PlayerController 컴포넌트의 Die() 메소드 실행 playerController.Die(); } } }

docs.unity3d.com/ScriptReference/Collider.html

Unity - Scripting API: Collider

docs.unity3d.com

Toplist

최신 우편물

태그