본문 바로가기

Unity3D/Kinematic

Unity 3D Kinematic

유니티 3D에서 Is Kinematic 옵션의 개념 및 사용


Kinematic 을 운동학이라고만 생각한다면 유니티의 Kinematic 개념을 이해하는 것은 어렵게 된다


Google에서 'What is Kinematic' 을 입력하고 검색하면 다음과 같이 Princeton 대학교에서 제공하는 Kinematic 에 대한 정의를 볼 수 있다

Kinematic(s)

(kinematics) the branch of mechanics concerned with motion without reference to force or mass


[ 외부 힘에 대한 영향이 없는 움직임 ]


위의 개념을 유니티의 Is Kinematic 에 적용해보면....


어떤 오브젝트에 미치는 외부의 힘을 물리엔진이 계산하여 해당 오브젝트가 적절히 물리학적으로 반응하도록 변환해야 하는데, Is Kinematic 옵션을 설정하면 '외부의 힘이 영향을 미치지 않는 오브젝트' 라고 선언하는 것이므로 이 옵션을 가진 오브젝트에 대해서는 물리엔진이 해당 오브젝트에게 가해지는 힘의 크기와 방향등을 계산하지 않는다는 것을 의미한다.

모든 오브젝트가 물리학적 외부 요인에 반응을 해야 하는 것은 아니므로 Is Kinematic 옵션을 설정하면 불필요한 시스템의 부하는 줄일 수 있을 것이다.


여기서는 Unity 3D에서 Is Kinematic 옵션에 대한 테스트를 위해 큐브로 구성된 간단한 프로젝트를 생성하고 몇가지 반응을 테스트하고자 한다


Is Kinematic 옵션에 대한 테스트

아래의 그림과 같이 새로 생성한 프로젝트에서 Scene 뷰에 Plane 과 Cube 하나를 생성하고 Hierarchy 뷰에서 Cube 를 선택한 후 Inspector 뷰를 보면 Box Collider 콤포넌트가 설정되어 있는 것을 확인할 수 있다. Collider 가 설정되어 있기 때문에 충돌을 탐지할 수 있다는 의미이다



Collider 콤포넌트를 가진 오브젝트 이므로 충돌을 탐지할 수 있는지 확인하기 위해서 우선 큐브에 회전을 가하는 아래의 스크립트를 생성하고 Hierarchy 뷰의 Cube안으로 드래그하여 Play 모드로 테스트한다.

#pragma strict


function Start () {

}


function Update () {

transform.Rotate(0,Time.deltaTime*50,0);

}


예상대로 큐브가 회전하는 것을 확인할 수 있었다


이번에는 충돌에 반응하는지 확인하기 위해 회전하는 큐브의 근처에 작은 큐를 놓고 필요시에 작은 큐브를 이동하여 의도적으로 충돌을 일으켜 보려고 한다

다음과 같이 작은 큐브를 Scene 뷰에 하나더 생성한다



큐브 2개를 생성할 때 아무런 설정도 없이 디폴트 상태에서 큐브가 회전하도록 스크립트만 설정했을 뿐이다. Play 모드로 실행이 될 때 Scene 뷰를 선택하고 작은 큐브를 회전하는 큐브로 이동하여 회전하는 큐브의 모서리에 충돌하도록 유도하면 아래의 그림과 같이 두 오브젝트의 영역이 서로 섞이는 것을 확인할 수 있다.



위와같은 환경에서도 충돌탐지는 가능한지 테스트하기 위해서 다음과 같이 스크립트에 약간 추가하고 다시 Play 모드로 테스트한다

#pragma strict


function Start () {

}


function Update () {

transform.Rotate(0,Time.deltaTime*50,0);

}


function OnCollisionEnter(collision:Collision) {

print("충돌:"+collision.transform.name);

}


테스트 결과는 충돌탐지가 안된다는 것이다.

게임을 구성하는 오브젝트가 충돌반응을 필요로 하지 않는다면 그대로 사용하는 것이 성능상 도움이 될 것이다. 물리엔진이 충돌반응을 계산하는데는 시스템 리소스를 점유하기 때문에 꼭 충돌반응이 필요한 경우에만 충돌탐지를 해야 할 것이다.


위에서 생성한 큐브는 강체(Rigidbody)가 아니기 때문에 유니티는 충돌반응이 필요없다고 간주하는 것이다. 강체는 관절체와 달리 그 형체가 변화되지 않는 오브젝트를 의미한다. 강체라면 다른 오브젝트에 충돌한 경우에도 그 형체가 변하지 않아야 하기 때문에 위의 경우처럼 다른 오브젝트가 관통하는 모습을 보여주어서는 안된다. 그러므로 강체로 선언된 오브젝트에 대해서는 물리엔진이 충돌을 탐지 기능을 작동하기 시작한다


회전하는 큐브를 Hierarchy 뷰에서 선택하고 Component > Physics > Rigidbody 를 선택하여 회전하는 큐브에 Rigidbody 콤포넌트를 추가하고 다시 Play 모드에서 의도적으로 충돌을 유도해 본다



위의 그림처럼 Rigidbody 콤포넌트를 추가한 후에야 충돌탐지가 되는 것을 확인할 수 있다.


이번에는 회전하는 큐브의 Rigidbody 콤포넌트 섹션에서 Is Kinematic 항목을 체크한 후에 다시 Play 모드로 실행하면서 충돌을 유도해본다



실행하여 충돌유도 테스트한 결과 Is Kinematic 옵션을 설정한 큐브는 충돌탐지가 안된다는 것이다

그렇다면 Rigidbody 콤포넌트를 설정하지 않은 경우와 동일한 결과이며 전혀 차이가 없는 것일까? 


회전하는 큐브는 외부의 힘에 반응하지 않는다는 선언을 한 상태(Is Kinematic)이므로 충돌에는 물리엔진이 충돌반응을 계산하지 않지만 외부에서 강체가 충돌한 경우에는 OnCollisionEnter 함수는 호출된다. 충돌해오는 작은 큐브가 강체가 아니기 때문에 충돌탐지가 안되는 것이며 작은 큐브에 Rigidbody 콤포넌트를 추가하면 OnCollisionEnter 함수가 호출된다. 또 회전하는 큐브가 강체로 선언된 경우에는 Is Kinematic 을 설정한 상태에서도 외부의 다른 오브젝트들에게는 일반적인 강체 오브젝트로 간주되므로 Rigidbody 콤포넌트를 추가한 경우와 추가하지 않은 경우에는 분명한 차이가 있다


특정 오브젝트가 외부의 힘에 물리적 반응을 보일 필요가 없다면 그 오브젝트에 Rigidbody 콤포넌트를 설정할 필요는 없지만 Rigidbody 를 설정하지 않으면 다른 제2의 오브젝트가 충돌할 때 제2의 오브젝트 입장에서는 Rigidbody 를 설정하지 않은 오브젝트와의 충돌을 탐지할 수 없는 것이다.