OasisW매뉴얼 English
섹션 7. 물리 방법 작성 대기 2

충돌 이벤트 받기

물체가 부딪히거나 어떤 범위에 들어왔을 때 무언가 일어나게 하려면 스크립트에서 충돌 이벤트를 받습니다. 이 페이지는 두 가지를 만듭니다. 상자가 바닥에 닿으면 색이 바뀌는 것(collisionstart)과, 상자가 통과하는 구역에 들어오면 구역이 사라지는 것(triggerenter)입니다.

이 페이지의 실측은 2026-10-29 oasisw.ai 에디터(판 표시 OasisW 7e2aa65, macOS Chrome)에서 충돌 판정 붙이기를 마친 씬으로 한 것입니다. 결과는 Launch한 게임을 두 번 실행해 브라우저 Console 로그와 스크립트 값으로 확인했습니다.

충돌과 트리거

충돌트리거
받는 엔티티Collision + Rigid BodyCollision만(Rigid Body 없음)
물체가 지나갈 수 있나막힙니다지나갑니다
받는 이벤트collisionstart, collisionend, contacttriggerenter, triggerleave
쓰는 곳바닥에 닿음, 벽에 부딪힘, 적과 부딪힘골인 지점, 아이템 줍기, 함정 구역

트리거로 쓰는 엔티티는 충돌 판정 붙이기에서 본 "Rigid Body가 없어 물체가 통과하는" 상태를 일부러 만든 것입니다.

2026-10-30 실측(1회)에서 Box(Dynamic)를 트리거 Zone 위로 떨어뜨려 이벤트가 어느 엔티티에 오는지 확인했습니다.

이벤트불리는 때받은 엔티티
collisionstart닿기 시작할 때. 튕겨 떨어졌다가 다시 닿으면 또 불립니다Box와 Plane 양쪽(둘 다 Rigid Body)
collisionend닿아 있다가 떨어질 때양쪽
contact닿아 있는 동안 계속. 약 4.6초에 332번 불렸습니다양쪽
triggerenter트리거 범위에 들어올 때트리거(Zone)만
triggerleave트리거 범위에서 나갈 때트리거(Zone)만

트리거를 지나간 Box 쪽에는 trigger 이벤트가 오지 않았습니다. 트리거 반응은 트리거 엔티티에 붙인 스크립트에서 받습니다. 바닥에 있던 Box를 applyImpulse(0, 6, 0)으로 띄우자 collisionend → Zone의 triggerenter·triggerleave → 다시 collisionstart 순서로 왔습니다. contact는 매 프레임 가까이 불리므로 점수·소리 같은 동작에는 collisionstart를 씁니다. 작성 대기 Rigid Body가 없는 엔티티가 트리거에 들어올 때 이벤트가 오는지 실측

시작하기 전에

에디터에서 직접 하기

1. 부딪히면 색 바꾸기(collisionstart)

  1. ASSETS의 + → Script로 hitColor 스크립트를 만듭니다.
  2. 아래 코드를 넣고 저장합니다. 오른쪽 CODE 칸에서 바로 고치고 Save를 눌러도 됩니다(코드 편집기 참고).
  3. Box에 Script 컴포넌트를 붙이고 + ADD SCRIPT로 hitColor를 붙입니다.
var HitColor = ow.createScript('hitColor');

// 부딪혔을 때 바꿀 색입니다
HitColor.attributes.add('hitColor', { type: 'rgb', default: [1, 0.3, 0.2], description: '부딪혔을 때 색' });

HitColor.prototype.initialize = function () {
    this.hits = 0;
    // 다른 물체와 부딪히기 시작할 때 한 번 불립니다
    this.entity.collision.on('collisionstart', this.onHit, this);
};

HitColor.prototype.onHit = function (result) {
    this.hits += 1;
    console.log('부딪힘: ' + result.other.name + ' (' + this.hits + '번째)');
    var material = new ow.StandardMaterial();
    material.diffuse = this.hitColor;
    material.update();
    this.entity.render.meshInstances[0].material = material;
};
줄뜻
attributes.add('hitColor', { type: 'rgb', … })에디터에서 고를 수 있는 색 칸을 만듭니다
collision.on('collisionstart', this.onHit, this)부딪히기 시작할 때마다 onHit을 부릅니다
result.other부딪힌 상대 엔티티. .name으로 이름을 읽습니다
new ow.StandardMaterial() … material = material새 머티리얼을 만들어 엔티티의 모양에 입힙니다

붙이면 hitColor 줄 아래에 코드의 처음 값(빨간색)으로 칠해진 색 칸이 나옵니다.

Box의 SCRIPT 컴포넌트에 붙은 hitColor와 빨간 색 칸
① 붙인 스크립트 ② 코드에서 만든 색 칸

Launch하면 상자가 바닥에 닿는 순간 빨갛게 바뀝니다.

Launch한 게임. 바닥에 떨어진 상자가 빨간색으로 바뀌었다
① 바닥에 닿아 색이 바뀐 Box

2. 이벤트가 여러 번 불리는 것 확인하기

실측에서 collisionstart는 상자가 떨어질 때마다 3번 불렸습니다(2회 실행 모두). 상자가 바닥에서 조금 튀어 올랐다가 다시 닿을 때마다 "부딪히기 시작"으로 세기 때문입니다. Rigid Body의 Restitution(튕김)이 처음 값 0.5라서 생기는 일로 보입니다.

점수를 올리거나 소리를 내는 동작이 여러 번 일어나면 안 될 때는 on 대신 once를 씁니다. 처음 한 번만 불립니다.

this.entity.collision.once('collisionstart', this.onHit, this);

실측에서 once로 바꾸자 불린 횟수가 1번이 됐습니다(2회 실행 모두).

3. 들어오면 반응하는 구역 만들기(triggerenter)

  1. HIERARCHY의 + → 3D → Box로 엔티티를 만들고 이름을 Zone으로 바꿉니다.
  2. Position 3, 2, 0, Scale 2, 0.2, 2로 바꿉니다. 떨어지는 Box가 지나가는 자리에 얇은 판이 생깁니다.
  3. Collision만 붙이고 Half Extents를 1, 0.1, 1로 바꿉니다. 충돌 범위는 Scale을 따라 커지지 않으므로 Scale의 절반을 직접 넣습니다. Rigid Body는 붙이지 않습니다.
Zone 엔티티. 상자 아래 초록 윤곽의 얇은 판, Half Extents 1, 0.1, 1, Scale 2, 0.2, 2
① 트리거로 쓸 Zone ② Half Extents 1, 0.1, 1 ③ Scale 2, 0.2, 2
  1. zoneAlert 스크립트를 만들어 아래 코드를 넣고, Zone에 붙입니다.
var ZoneAlert = ow.createScript('zoneAlert');

ZoneAlert.prototype.initialize = function () {
    this.entered = 0;
    // 리지드 바디가 있는 엔티티가 이 범위에 들어올 때 불립니다
    this.entity.collision.on('triggerenter', this.onEnter, this);
};

ZoneAlert.prototype.onEnter = function (other) {
    this.entered += 1;
    console.log('구역에 들어옴: ' + other.name);
    // 구역을 숨깁니다
    this.entity.render.enabled = false;
};

triggerenter는 collisionstart와 달리 상대 엔티티를 바로 넘겨줍니다(result.other가 아니라 other).

Launch하면 상자가 Zone을 그대로 통과하고, 그 순간 Zone이 사라집니다. 상자는 바닥에 닿아 빨갛게 바뀌고 멈춥니다. 실측에서 triggerenter는 1번 불렸습니다(2회 실행 모두).

로그 보기

스크립트의 console.log는 게임 화면에는 나오지 않습니다. Launch 탭에서 브라우저 개발자 도구를 열고(Windows F12, 맥 Cmd+Option+I) Console 탭을 봅니다. 실측에서는 다음 줄이 순서대로 찍혔습니다.

구역에 들어옴: Box
부딪힘: Plane (1번째)
부딪힘: Plane (2번째)
부딪힘: Plane (3번째)

로그 오른쪽에는 스크립트 파일 주소와 줄 번호가 붙습니다. 에디터 맨 아래 CONSOLE에는 게임의 로그가 나오지 않았습니다. Launch를 4번 하는 동안 CONSOLE에는 에디터를 열 때 나온 첫 줄 하나만 있었습니다.

AI에게 맡기기

"부딪히면 무엇을 한다"는 요청은 AI가 스크립트를 만들어 붙이는 일입니다. 어느 엔티티가 무엇과 닿았을 때, 무엇이 몇 번 일어나는지를 적습니다. "한 번만"을 적지 않으면 위처럼 여러 번 일어날 수 있습니다.

요청문
Box가 Plane에 처음 닿으면 Box를 빨간색으로 바꿔 주세요. 두 번째부터는 아무 일도 일어나지 않게 해 주세요. 요청한 것 외에는 손대지 마세요.

작성 대기 위 요청문을 현재 판에서 3회 보내 결과(만든 스크립트, on/once 여부) 기록

확인하기

  • Launch해서 부딪히는 순간 원하는 일이 일어나는지 봅니다.
  • 브라우저 Console에서 이벤트가 몇 번 불렸는지 봅니다. 한 번이어야 하는 동작이 여러 번 일어나면 once나 조건을 씁니다.
  • 트리거 구역은 물체가 통과하는지, 들어올 때 이벤트가 불리는지 함께 봅니다.

막혔을 때

증상원인해결
부딪혀도 아무 일도 없다스크립트가 붙지 않았거나, 물리가 동작하지 않습니다엔티티의 SCRIPT에 스크립트 줄이 있는지, Ammo 폴더와 Rigid Body가 있는지 봅니다(충돌 판정 붙이기)
한 번만 일어나야 할 일이 여러 번 일어난다튕길 때마다 collisionstart가 다시 불립니다on을 once로 바꿉니다
구역에 들어가도 triggerenter가 불리지 않는다구역에 Rigid Body가 붙어 있으면 트리거가 아니라 막는 물체가 됩니다구역의 Rigid Body를 떼고 Collision만 둡니다
들어간 물체의 스크립트에서 triggerenter가 불리지 않는다trigger 이벤트는 트리거 엔티티에만 옵니다트리거 엔티티(구역)에 스크립트를 붙이고 거기서 받습니다
구역 일부에서만 반응한다Collision 범위가 Scale을 따라 커지지 않습니다Half Extents를 보이는 크기의 절반으로 맞춥니다
console.log가 어디에도 안 보인다게임 화면과 에디터 CONSOLE에는 나오지 않습니다Launch 탭의 브라우저 개발자 도구 Console을 엽니다

다음으로

원고 physics/collision-events.html