Notice
Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Today
Total
관리 메뉴

만재송

[Cocos Creator] Collider Component 정복하기 본문

프로그래밍/COCOS Creator

[Cocos Creator] Collider Component 정복하기

만재송 2018. 2. 1. 18:34

Collider Component


cocos creator 에서 물리 시스템은 2가지 기능을 제공하고 있다. cocos2d-js 에서 사용하는 chipmunk와 비슷한 기능을 하는 Box2d 물리 엔진과, body의 기능을 하지않는 즉, 중력, 회전, 속도 같은 기능처리를 하지않고 오직 충돌 검사만 수행하는 Collider Component 가 있다. 그 중 Collider Component 를 통하여 오직 서로간의 충돌하는 기능만을 수행하고 싶을 때 코드가 복잡한 물리엔진 대신 간단한 코드로 충돌처리를 확인할 수 있다. Collider Component 를 어떻게 사용하고 효과적으로 사용할 수 있는지 알아보자.

 


컴포넌트 추가


먼저 Creator 테스트 프로젝트를 하나 만들자 (javaScript, typeScript 상관없다). 테스트를 위해서 Sprite Node 2개와 Label 1개를 아래처럼 Node Tree 에 추가하자.



다음으로 두개의 Sprite Node 에 Collider Component 를 추가하자. Node Tree 에서 해당 Node 를 클릭하고 Add Component 에서 Add Collider Component 를 클릭하여 원하는 모양의 Collider 를 추가할 수 있다. 



Collider 는 Box, Circle, Polygon 이 있다. Sprite의 모양을 보고 원하는 Collider 를 추가하면 된다. 그럼 box Sprite는 Box Collider 를 orange Sprite에는 Circle Sprite를 추가하자. 그럼 아래와 같이 Sprite를 무언가로 감싸고 있는 선이 생길것이다.



기본 세팅이 완료되었으니 이제 스크립트를 작성해보자!



코드작성


오렌지를 움직여서 박스와 충돌했을때 Label을 hit로 변경하고 박스를 없애는 코드를 구현해 보자. Orange 스크립트를 생성하고 파일을 열어보자. 그다음 아래와 같이 코드를 작성한다.


cc.Class({
extends: cc.Component,

properties: {
},

onLoad: function () {
this.manager = cc.director.getCollisionManager();
this.manager.enabled = true;
this.manager.enabledDebugDraw = true;
}
});


onLoad 는 해당 Node 가 active 될 때 최초 1번 실행되는 메서드이다. 위의 코드는 Collider Component 를 사용하기 위해서 작성하는 CollisionManager이다. 해석하면,


1. cc.director.getCollisionManager() 를 호출해서 CollisionManager를 가져온 후 manager 프로퍼티에 넣는다.

2. manager.enabed 를 true 로 설정하여 CollisionManager 를 사용하겠다고 알린다.

3. manager.enabledDebugDraw 를 true 로 설정하여 Collider Component 가 있는 Node 의 충돌범위를 실선으로 확인한다.


3번 같은 경우는 개발자가 테스트할때는 true로 하고 게임을 배포할 때는 false로 해야한다. 그렇지 않으면 모든 Collider Component 가 있는 Node 에 선이 생겨 버그처럼 보여질수도 있다.


CollisionManager 를 추가하면 3개의 메서드를 오버라이드 할 수 있다.


onCollisionEnter: function (other, self) {
},

onCollisionStay: function (other, self) {
},

onCollisionExit: function (other, self) {
},


onCollisionEnter 는 다른 Collider Component가 있는 Node 와 충돌을 하자마자 호출 되는 메서드다. onCollisionStay 는 onCollisionEnter 가 호출 된 후 그 물체와 계속 충돌되고 있는 상태면 Stay를 매 프레임마다 호출한다. 마지막으로 onCollisionExit 는 물체와 충돌이 끝난 후에 호출되는 메서드다. 


또한 3개의 메서드는 모두 2개의 파라미터 other와 self를 가진다. other 는 상대방의 Collider Component 객체고 self는 자신의 Collider Component 객체다. 필자가만든 테스트를 예시로 하면 other 는 박스의 Collider Component 객체고 self 는 오렌지의 Collider Component 객체다.


그럼 3개의 메서드가 호출이 잘되는 지 테스트를 한번 해보자. 3개의 메서드에 각각 호출을 알릴 수 있는 콘솔을 추가하고, move 액션을 이용하여 오렌지를 움직여보자.


cc.Class({
extends: cc.Component,

properties: {
},

onLoad: function () {
this.manager = cc.director.getCollisionManager();
this.manager.enabled = true;
this.manager.enabledDebugDraw = true;

this.node.runAction(cc.moveBy(5, -1000, 0));
},

onCollisionEnter: function (other, self) {
console.log("Enter 진입");
},

onCollisionStay: function (other, self) {
console.log("Stay 진입");
},

onCollisionExit: function (other, self) {
console.log("Exit 진입");
}
});


위와 비슷하게 코드를 작성하고 저장한 후 creator editor 창으로 가보자. 오렌지를 움직이기 위해서는 작성한 코드를 오렌지 Node 에 Component 로 추가해야한다. Node Tree 에서 오렌지를 클릭 후 Orange 스크립트 파일을 추가하자. 그리고 실행하면 아래와 같이 콘솔에 값이 호출 될 것이다.



모든 구현이 거의 완성된 것 같다! 이제 부딪쳤을 때 Label을 hit로 변경하고 박스를 없애는 코드를 추가하자. 우리는 최초 부딪쳤을 때 박스를 없애면 되니 Enter 메서드만 사용하면 된다. onCollisionEnter 메서드를 아래와 같이 수정하자.


onCollisionEnter: function (other, self) {
console.log("Enter 진입");
other.node.destroy();
this.label.string = "hit";
},


label을 변경할려면 properties에 label 프로퍼티를 추가해야한다.


properties: {
label: cc.Label
},


저장을하고 실행을하면 안된다! 아직 우리는 label을 오렌지에 추가하지 않았다. 오렌지 Node를 클릭하여 변경할 라벨을 끌어서 Label 에 추가하자.



이제 실행해보자. 오렌지가 박스에 충돌하자마자 박스가 사라지는 모습을 볼 수 있을것이다.




Group


cocos2d 에서 물리를 사용한 사람이라면 group의 기능을 알것이다. cocos creator에서도 비슷한 기능을하지만, 충돌대상을 정할 수 있다. 


group을 통해서 코드를 수정하지 않고 오렌지와 박스가 충돌을했을 때 박스가 사라지지 않게 구현해보자. cocos creator 에서 Project -> Project Settings 를 클릭하면  Group Manager 가 처음에 보여질것이다. Group Manager 는 group 를 추가하여 어떤 group 과는 충돌을 허용하고 어떤 group 과는 충돌을 허용하지 않는 기능을 코드없이 구현할 수 있다. 그럼 Add Group 를 2번 클릭하여 Orange 와 Box group 를 추가하고 아래와 같이 체크박스에 체크하자.



위의 그림에서 Group Collide Map 은 충돌 대상을 지정하는 체크박스다. 어떤 group 와 충돌을 하고 싶으면 체크박스를 체크하면 해당 group 과는 충돌이 허용된다. 예를들면 Orange 와 Box 가 있는 2번째 줄 첫번째 체크박스를 체크하면 박스와 오렌지는 서로충돌을 하게된다. 


작성이 완료되었으면 Save를 하고 창을 닫은 후 실행을 해보면 여전히 오렌지는 박스와 충돌할것이다. 우리는 Manager에서 선언만 했지, 실제 Node 에게 group 을 할당을 해주지 않았다.


Node Tree 에서 오렌지 Node 를 클릭한 후 Node Component 젤 밑에 있는 Group 을 변경하자. 아무것도 건들지 않았으면 default 로 설정되 있을것이다. 각각 Node 에 오렌지는 Orange 로, 박스는 Box 로 변경하자.



변경한 후 게임을 실행하면 충돌을 해도 박스가 사라지지 않는다. 중요한것은 콘솔도 호출이 되지 않는다. 즉, 충돌을 허용하지 않는 group 끼리는 Coliision 메서드가 호출이 되지 않는다.




기타 기능


Collider Component 에는 2가지의 공통기능이있다. 첫번째는 Editing이다. Editing 을 체크하면 editor 에서 해당 Node 에 점이 생긴다. 그 점을이용하여 충돌범위를 변경할 수 있다. 아래는 박스의 충돌범위를 변경한 모습이다.


 


두번째는 tag 이다. tag는 cocos2d 에서의 collisionType 과 같은 기능을한다. 해당 Node에 tag 값을 줘서 물체가 부딪쳤을 때 스크립트 상에서 other 의 tag 값을 확인한 후 물체를 제거할지 안할지 선택할 수 있다. 박스의 tag 값을 2로 변경하고 Orange 스크립트에서 onCollisionEnter 메서드를 아래와 같이 수정해보자. 


onCollisionEnter: function (other, self) {
console.log("Enter 진입");
if (other.tag === 2) {
other.node.destroy();
this.label.string = "hit";
}
},


위의 코드는 부딪친 상대의 tag 가 2일 때 물체를 없애는 코드다. 저장한 후 코드를 실행해보면 정상적으로 박스가 없어지게 된다. (물론 아까 설정한 group 값은 default 로 다시 설정한다.)



Collider Component 를 마치며


Collider Component 를 통해서 힘든 충돌처리 구현을 3개의 메서드로 간단하게 구현할 수 있게된다. 예로들어 똥피하기 게임을 만든다고 할때 일정한 속도로 떨어지는 똥이 바닥에 부딪쳤을 때 Collider Component 를 사용하면 메서드 1개에 단 1줄이면 구현이 가능하다. 이렇게 게임 라이브러리는 점점 우리가 코드작성을 쉽게해주도록 해주는것 같다. 필자가 cocos2d 에서 cocos creator 로 넘어온 이유도 이런 편리한 기능이 많아져서 인 것 같다. cocos creator 보다 더좋은 기능이 있는 툴이 나온다면 물론 툴을 바꿀 의향이있다. (있다면 말좀해줘라....)




참고


Comments