Physics - kuimoani/defold GitHub Wiki
Physics
Defold๋ 2D ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์ ์ ์ํด Box2D ๋ฌผ๋ฆฌ ์์ง์ ๊ฐ๋ํ ๋ฒ์ ์ ํฌํจํ๊ณ ์์ผ๋ฉฐ ๋ดํด์ ๋ฌผ๋ฆฌ ๋ฒ์น์ ๋ฐ๋ผ ๋ค๋ฅธ ์ข ๋ฅ์ ์ถฉ๋ ์ค๋ธ์ ํธ๊ฐ์ ์ํธ์์ฉ์ ์๋ฎฌ๋ ์ด์ ํฉ๋๋ค. ์ด ๋ฉ๋ด์ผ์ ๋ฌผ๋ฆฌ๊ฐ ๋์ํ๋ ๋ฐฉ๋ฒ์ ๊ดํด ์ค๋ช ํฉ๋๋ค.
Collision objects
์ถฉ๋ ์ค๋ธ์ ํธ๋ ๋ฌผ๋ฆฌ ๋์์ผ๋ก ๊ฒ์ ์ค๋ธ์ ํธ๋ฅผ ํ์ฅํ๋๋ฐ ์ฌ์ฉ๋๋ ์ปดํฌ๋ํธ์ ๋๋ค. ์ถฉ๋ ์ค๋ธ์ ํธ๋ ์๋ก ๋ค๋ฅธ ๋ฌผ๋ฆฌ ์์ฑ(๋ฌด๊ฒ, ๋ฐ๋ฐ๋ ฅ, ๋ง์ฐฐ๋ ฅ ๊ฐ์)์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ํ ๊ฐ ํน์ ๊ทธ ์ด์์ ๋ชจํ(shape) ์ปดํฌ๋ํธ๋ฅผ ์ฒจ๋ถํด์ ๊ณต๊ฐ ํ์ฅ์ ํ ์ ์์ต๋๋ค. Defold๋ ์ฌ๋ฌ ์ข ๋ฅ์ ์ถฉ๋ ์ค๋ธ์ ํธ๋ฅผ ์ง์ํ๊ณ ์์ต๋๋ค:
Static objects
์ ์ ๊ฐ์ฒด๋ ์ค์ค๋ก ๋ฐ์ํ์ง๋ ์์ง๋ง ๋ค๋ฅธ ์ค๋ธ์ ํธ๊ฐ ์ถฉ๋ํ๊ฒ ๋๋ฉด ๋ฐ์ํฉ๋๋ค. ์ด๋ ์์ง์ด์ง ์๋ ๊ฑด์ถ๋ฌผ ๊ฐ์ ์งํ(๋ฐ๋ฅ, ๋ฒฝ ๋ฑ๋ฑ)์ ์ ์ฉํฉ๋๋ค(์ฑ๋ฅ์ ์ด๋์). ์ ์ ์ค๋ธ์ ํธ๋ ์์ง์ด๊ฑฐ๋ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
Dynamic objects
๋ฌผ๋ฆฌ ์์ง์ ๋ชจ๋ ์ถฉ๋(collision)์ ํด๊ฒฐํ๊ณ ํ(forces)์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ํฉ๋๋ค. ์ด๋ ํ์ค์ ์ผ๋ก ์์ง์ฌ์ผ ํ๋ ์ค๋ธ์ ํธ์ ์ ์ฉํฉ๋๋ค. ์๋์ผ๋ก ์ ์ดํ ์ ์๋ ์ ์ผํ ๋ฐฉ๋ฒ์ ์ด ๋์ ์ค๋ธ์ ํธ์ ํ์ ๊ฐํ๋ ๊ฒ ๋ฟ์ ๋๋ค.
Kinematic objects
์ด ํ์ ์ ๋ค๋ฅธ ๋ฌผ๋ฆฌ ์ค๋ธ์ ํธ์ ์ถฉ๋ํ์ง๋ง ์ถฉ๋์ ํด๊ฒฐํ๋ ์์ ์ ์ง์ ์ฒ๋ฆฌ(์๋๋ฉด ๊ทธ๋ฅ ๋ฌด์ํ๊ฑฐ๋)ํด์ผ ํฉ๋๋ค. ํค๋ค๋งํฑ ์ค๋ธ์ ํธ๋ ์ถฉ๋์ด ๋ฐ์ํ๋ฉด์ ๋ชจ๋ ๋ฆฌ์ก์ ์ ์ง์ ์ธ๋ฐํ๊ฒ ์ ์ดํ๋ ๊ฒ์ ์ํ๋ ๊ฒฝ์ฐ์ ์ ์ฉํฉ๋๋ค.
Triggers
ํธ๋ฆฌ๊ฑฐ๋ ๊ฐ๋จํ ์ถฉ๋์ ๋ฑ๋กํ๋ ์ค๋ธ์ ํธ์ ๋๋ค. ์ด๋ ์ด๋ค ์ค๋ธ์ ํธ(ํ๋ ์ด์ด ์บ๋ฆญํฐ ๊ฐ์)๊ฐ ํน์ ํ ์ง์ ์ ๋๋ฌํ์ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ๊ฐ ํ์ํ ๊ฒ์๋ก์ง์ ์ ์ฉํฉ๋๋ค.
Editing collision objects
์๋ํฐ๋ ์ถฉ๋ ์ค๋ธ์ ํธ๋ฅผ ๊ฒ์ ์ค๋ธ์ ํธ์ ์ฝ๊ฒ ๋ฐฐ์นํ ์ ์๊ฒ ํด ์ค๋๋ค.

์ถฉ๋ ์ค๋ธ์ ํธ๋ ํ๋ ํน์ ๊ทธ ์ด์์ ๋ฌผ๋ฆฌ ๋ชจํ(physics shapes)์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
- Box shapes
- Sphere shapes
- Capsule shapes (3D ๋ฌผ๋ฆฌ์์๋ง ๋์ํจ!)
๋น์ ์ ์์ ๋ชจํ(shape)์ ์ถ๊ฐํ๊ณ ๋ณํ ๋๊ตฌ(transform tool)์ ์ฌ์ฉํ์ฌ ์ค์ผ์ผ, ํ์ , ํฌ์ง์ ์ ์์ ํ ์ ์์ต๋๋ค. ๊ฐ ์ถฉ๋ ์ค๋ธ์ ํธ๋ ์๋์ ๊ฐ์ ์์ฑ๋ค์ ๊ฐ์ง๋๋ค.

"Collision Shape" ์์ฑ์ ์ผ๋ฐ ์์ ๋ชจํ(primitive shape)์ ์ฌ์ฉํ์ง ์๋ ํ์ผ๋งต์ ์งํ(geometry)์ ์ฌ์ฉํฉ๋๋ค. ์์ธํ ๊ฒ์ Tilesource collision shapes ์์ ์ดํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
Type ์์ฑ์ ์ถฉ๋ ์ค๋ธ์ ํธ์ ์ข ๋ฅ("Dynamic", "Kinematic", "Static", "Trigger")๋ฅผ ์ค์ ํ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. "Dynamic"์ผ๋ก ์ค์ ํ๋ฉด Mass(์ง๋) ์์ฑ์ 0์ด ์๋ ๊ฐ์ผ๋ก ์ค์ ํด์ผ ํฉ๋๋ค. ๋ํ ๋์ (Dynamic) ํน์ ์ ์ (Static) ์ค๋ธ์ ํธ๋ฅผ ์ํด์๋ Friction(๋ง์ฐฐ๋ ฅ) ๊ณผ Restitution(๋ฐ๋ฐ๋ ฅ) ๊ฐ์ ์ค์ ํด์ผ ํฉ๋๋ค.
๋ง์ฝ "Dynamic" ํ์ ์ผ๋ก ์ค์ ํ๊ณ mass๋ฅผ 0์ด ์๋ ๊ฐ์ผ๋ก ์ ํ ํ๋ ๊ฒ์ ๊น๋นก ํ๋ค๋ฉด ์ปดํ์ผ์ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค: "ERROR: GAMESYS: Invalid mass 0.000000 for shape type 0"
Friction
๋ง์ฐฐ๋ ฅ์ ์ค๋ธ์ ํธ๊ฐ ๋ค๋ฅธ ์ค๋ธ์ ํธ๊ณผ ๋ถ์ด์ ํ์ค๊ฐ ์๊ฒ ๋ฏธ๋๋ฌ์ง๊ฒ ๋ง๋๋ ๊ฒ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ์ด ๊ฐ์ ์ผ๋ฐ์ ์ผ๋ก 0(๋ง์ฐฐ๋ ฅ์ด ์ ํ์์ผ๋ฏ๋ก ์์ฒญ ๋ฏธ๋๊ฑฐ๋ฆผ)๊ณผ 1(๊ฐ๋ ฅํ ๋ง์ฐฐ๋ ฅ์ผ๋ก ์์ฒญ ๊ฑฐ์น ์ด์ง) ์ฌ์ด๋ก ์ค์ ๋๋ฉฐ ์์ ๊ฐ(positive value)๋ง ์ ํจํฉ๋๋ค.
๋ง์ฐฐ๋ ฅ์ ๊ฐ๋๋ ์์งํญ๋ ฅ(normal force: ์ฟจ๋กฑ ๋ง์ฐฐ(Coulomb friction)์ผ๋ก๋ ๋ถ๋ฆผ)์ ๋น๋กํฉ๋๋ค. ๋ง์ฐฐ๋ ฅ์ด ๋ ๋ชจํ(shapes) ์ฌ์ด์์ ๊ณ์ฐ๋๋ฉด, ๋ ์ค๋ธ์ ํธ์ ๋ง์ฐฐ๊ฐ์ด ๊ธฐํํ๊ท (geometric mean)์ ์ํด ๊ฒฐํฉ๋ฉ๋๋ค.
combined_friction = math.sqrt(shape1_friction * shape2_friction)
์ฆ, ๋ ์ค๋ธ์ ํธ ์ค ํ๋๋ผ๋ ๋ง์ฐฐ์ด ์๋ ๊ฒฝ์ฐ์ ์ด๋ค ์ฌ์ด์ ์ ์ด๋ฉด์ ๋ง์ฐฐ์ด ์๋ ๊ฒ์ผ๋ก ๊ณ์ฐ๋ฉ๋๋ค.
Restitution
๋ฐ๋ฐ๋ ฅ ๊ฐ์ ์ค๋ธ์ ํธ์ ํ์ฑ(bounciness)์ ์ค์ ํฉ๋๋ค. ์ด ๊ฐ์ ์ผ๋ฐ์ ์ผ๋ก 0(๋นํ์ฑ ์ถฉ๋๋ก์ ์ค๋ธ์ ํธ๊ฐ ์ ํ ํ๊ธฐ์ง ์์)์์ 1(์์ ํ ํ์ฑ ์ถฉ๋๋ก์ ์ค๋ธ์ ํธ์ ์๋์ ๊ฐ์ ๊ฐ์ผ๋ก ํ๊ฒจ๋๊ฐ) ์ฌ์ด๋ก ์ค์ ๋ฉ๋๋ค.
๋ ์ค๋ธ์ ํธ ์ฌ์ด์ ๋ฐ๋ฐ๋ ฅ์ ์๋ ๊ณต์์ผ๋ก ๊ฒฐํฉ๋ฉ๋๋ค.
combined_restitution = math.max(shape1_restitution, shape2_restitution)
๋ชจํ(shape)์ด ์ฌ๋ฌ ๊ฐ์ ์ ์ด๋ฉด(multiple contacts)์ผ๋ก ๊ฐ๋ฐ ๋์๋ค๋ฉด, Box2D๊ฐ iterative solver(๋ฐ๋ณต์ ์ผ๋ก ๋ฌผ๋ฆฌ ์ถฉ๋์ ํด๊ฒฐํ๋ ํด๊ฒฐ์ฌ)๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ฐ๋ฐ๋ ฅ์ ๋๋ต์ ์ผ๋ก ์๋ฎฌ๋ ์ด์ ๋ฉ๋๋ค. ๋ํ Box2D๋ ์ถฉ๋ ์๋๊ฐ ๋๋ฌด ์์ ๋์๋ ๋นํ์ฑ ์ถฉ๋(inelastic collisions)์ ์ฌ์ฉํ์ฌ bounce-jitter(๋ฐ์ด์ค์์ ๋๋ ๋จ๋ฆฌ๋ ํ์)๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
Linear and angular damping
๊ฐ์ (damping)๋ ๋ชธ์ฒด์ ์ ํ(linear) ์๋์ ๊ฐํ(angular) ์๋๋ฅผ ๊ฐ์ ์ํต๋๋ค. ์ด๋ ์ ์ด๋ฉด์์๋ง ๋ฐ์ํ๋ ๋ง์ฐฐ๋ ฅ๊ณผ๋ ๋ค๋ฅด๋ฉฐ, ๊ณต๊ธฐ๋ณด๋ค ๋ฌด๊ฑฐ์ด ๊ณต๊ฐ์ ์ง๋๊ฐ๋ฏ์ด ๋ ๋ค๋๋ ๊ฒ์ ํํํ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ ํจํ ๊ฐ์ 0๋ถํฐ 1๊น์ง์ ๊ฐ์ ๋๋ค.
Box2D๋ ์์ ์ฑ๊ณผ ์ฑ๋ฅ๋๋ฌธ์ ๊ฐ์ ๊ฐ์ ๋๋ต์ ์ผ๋ก ๊ณ์ฐํฉ๋๋ค. ์์ ๊ฐ์ ๊ฐ์ ํจ๊ณผ๋ ์๊ฐ ํ๋ฆ์ ์ํฅ์ ๋ฐ์ง ์๋ ๋ฐ๋ฉด, ํฐ ๊ฐ์ ๊ฐ์ ์๊ฐ ํ๋ฆ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. ๋ง์ฝ ๊ณ ์ ๋ ์๊ฐ ๊ฐ๊ฒฉ(fixed time step)์ผ๋ก ๊ฒ์์ ์คํํ๋ค๋ฉด, ์ด๊ฒ์ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค.
Locked rotation
์ด ์์ฑ์ ์ค๋ช ํ๋ฉด ์ด๋ค ์ํฅ์ ๋ฏธ์น๋์ง์ ๊ด๊ณ ์์ด ์ถฉ๋ ์ค๋ธ์ ํธ์ ํ์ ์ ์์ ํ ๋นํ์ฑํ ํฉ๋๋ค.
Group and Mask
์ด ๊ธฐ๋ฅ์ ํน์ ์ ํ์ ์ค๋ธ์ ํธ๊ฐ ๋ค๋ฅธ ํน์ ์ ํ์ ์ค๋ธ์ ํธ์ ์ถฉ๋ํ๋ฉด์ ๋ ๋ค๋ฅธ ์ 3์ ์ค๋ธ์ ํธ์๋ ์ถฉ๋ํ์ง ์๊ฒ ํํฐ๋งํ๋๋ฐ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์๋์ ๊ฐ์ด ๋ฉํฐํ๋ ์ด์ด ์ํ ๊ฒ์์์ ํ์ํ ์ ์์ต๋๋ค.
- ํ๋ ์ด์ด ์บ๋ฆญํฐ๊ฐ ์ด์ ์ค๋ธ์ ํธ๋ฅผ ๋ฐ์ฌํจ
- ์ด์ ์ค๋ธ์ ํธ๋ ์ ์ค๋ธ์ ํธ์ ์ถฉ๋ ํด์ผํจ
- ์ด์ ์ค๋ธ์ ํธ๋ ํ๋ ์ด์ด ์บ๋ฆญํฐ์๋ ์ถฉ๋ํ์ง ๋ง์์ผ ํจ
- ํ๋ ์ด์ด ์บ๋ฆญํฐ๋ ์ ์ค๋ธ์ ํธ์ ์ถฉ๋ ํด์ผํจ
- ํ๋ ์ด์ด์ ์ ์ค๋ธ์ ํธ๋ค์ ๊ฒ์์ธ์์ ํ์ผ(tile)์๋ ์ถฉ๋ํจ
๋ฌผ๋ฆฌ ์์ง์ ๋ฌผ๋ฆฌ ์ค๋ธ์ ํธ๋ฅผ ๊ทธ๋ฃนํ ํ๊ณ ์ด๋ป๊ฒ ์ถฉ๋ํด์ผ ํ๋์ง์ ๋ํด ํํฐ๋ง ํ ์ ์๊ฒ ํด ์ค๋๋ค. ์ด๋ ์ถฉ๋ ๊ทธ๋ฃน(collision group)์ ์ด๋ฆ์ผ๋ก ๋ค๋ฃฐ ์ ์์ต๋๋ค. ์๋ ๋ ๊ฐ์ง ์์ฑ์ ์ด๋ป๊ฒ ์ค๋ธ์ ํธ๊ฐ ๋ค๋ฅธ ์ค๋ธ์ ํธ์ ์ถฉ๋ํ๋์ง๋ฅผ ์ ์ดํฉ๋๋ค.
Group
์ค๋ธ์ ํธ๊ฐ ์ํด์ผ ํ๋ ์ถฉ๋ ๊ทธ๋ฃน์ ์ด๋ฆ์ ๋๋ค. 16๊ฐ์ ๋ค๋ฅธ ๊ทธ๋ฃน์ ๊ฐ์ง ์ ์์ผ๋ฉฐ ๋น์ ์ ๊ฒ์์ ์ด์ธ๋ฆฌ๋ ์ด๋ฆ(์๋ฅผ ๋ค์ด "players", "bullets", "enemies", "world" ๋ฑ๋ฑ)์ผ๋ก ์ง์ผ๋ฉด ๋ฉ๋๋ค.
Mask
์ด ์ค๋ธ์ ํธ๊ฐ ์ถฉ๋ํด์ผ ํ๋ ๋ค๋ฅธ ๊ทธ๋ฃน์ ์ด๋ฆ์ ๋๋ค. ๊ทธ๋ฃน ํ๋์ ์ด๋ฆ์ ์ง์ ํ๊ฑฐ๋ ์ผํ(,)๋ก ์ฌ๋ฌ ๊ทธ๋ฃน์ ์ด๋ฆ์ ์ง์ ํด๋ ๋ฉ๋๋ค. ๋ง์ฝ ์ด Mask ํ๋๊ฐ ๋น๊ฐ์ผ๋ก ๋์ด ์๋ค๋ฉด, ์ค๋ธ์ ํธ๋ ์๋ฌด๊ฒ๋ ์ถฉ๋ํ์ง ์์ต๋๋ค.
๊ฐ ์ถฉ๋์ ๋ ๊ฐ์ ์ค๋ธ์ ํธ์ ๊ด๋ จ๋์ด ์์ผ๋ฏ๋ก, ๋ ์ค๋ธ์ ํธ ์ํธ๊ฐ์ Group์ ์ด๋ฆ์ Mask ํ๋์ ์๋ก ์ง์ ํด์ผ ํฉ๋๋ค.

์์ ์ํ ์ํ ๊ฒ์์ ์ถฉ๋ ๊ณํ์ ๋ฌ์ฑํ๋ ค๋ฉด, ์๋์ ๊ฐ์ด ์ค์ ํ๋ฉด ๋ฉ๋๋ค.
Players
Group: "players", Mask: "world, enemies"
Bullet
Group: "bullets", Mask: "enemies"
Enemies
Group: "enemies", Mask: "players, bullets"
World
Group: "world", Mask: "players, enemies"
Tilesource collision shapes
Defold ์๋ํฐ์๋ ํ์ผ ์์ค๋ฅผ ์ํ ๋ฌผ๋ฆฌ ๋ชจ์(shape)์ ๋น ๋ฅด๊ฒ ์์ฑํ๋ ๋๊ตฌ๊ฐ ์์ต๋๋ค. ํ์ผ์์ค ์๋ํฐ์์, ์ถฉ๋์ ์ํด ๊ธฐ์ด๋ก ์ฌ์ฉํ ์ด๋ฏธ์ง๋ฅผ ์ ํํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ์ด ์๋ํฐ๋ 100%๋ก ํฌ๋ช ํ์ง ์์ ํฝ์ ์ ๊ณ ๋ คํ์ฌ, ๊ฐ ํ์ผ ์ฃผ๋ณ์ผ๋ก ๋ณผ๋กํ ๋ชจํ(convex shape)์ ์๋์ผ๋ก ์์ฑํฉ๋๋ค.

์ด ์๋ํฐ๋ ํ์ผ์ ํ ๋น๋ ์ถฉ๋ ๊ทธ๋ฃน์ ์์์ผ๋ก ์ด ๋ชจํ(shape)๋ค์ ๊ทธ๋ ค์ค๋๋ค. ํ์ผ ์์ค๋น ์ฌ๋ฌ ๊ฐ์ ์ถฉ๋ ๊ทธ๋ฃน์ ๊ฐ์ง ์ ์์ผ๋ฉฐ ์๋ํฐ์ ์ํด ๊ทธ๋ฃน ์์์ด ์๋์ผ๋ก ์ ํ๋ฉ๋๋ค.

ํ์ผ ๋ฌผ๋ฆฌ ๋ชจ์(tile physics shape)์ ํน์ ํ ์ถฉ๋ ๊ทธ๋ฃน์ผ๋ก ์ค์ ํ๊ณ ์ถ๋ค๋ฉด, group์ ์ ํํ๊ณ shape์ ํด๋ฆญํ์ธ์. ์ด๋ค ์ถฉ๋ ๊ทธ๋ฃน์ผ๋ก๋ถํฐ ํ์ผ ๋ชจํ(tile shape)์ ์ญ์ ํ๋ ค๋ฉด, "Tile source"์ ์ต์์(root)๋ฅผ ์ ํํ๊ณ ํ์ผ์ ํด๋ฆญํ์ธ์.
ํ์ผ ์์ค๋ก๋ถํฐ ์ถฉ๋ ๋ชจํ(collision shape)์ ์ฌ์ฉํ๋ ค๋ฉด, ์ํ๋ ๊ฒ์ ์ค๋ธ์ ํธ์ ์ถฉ๋ ์ค๋ธ์ ํธ(Collision Object)๋ฅผ ๋ง๋ค๊ณ Collision Shape ์์ฑ์ ํ์ผ ์์ค๋ฅผ ์ ํํ๋ฉด ๋ฉ๋๋ค.

- ํ์ผ ๋งต์ ์ฐ๊ฒฐ๋ ํ์ผ์์ค๊ฐ ์ถฉ๋์ ์ํด ์ค์ ๋ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ง๊ณ ์๋์ง ํ์ธํ์ธ์. ์ด๋ ์๋ํฐ ์ฐฝ์์ ํ ์ค์ณ์ ์๋จ์ ์ ์ผ๋ก ๋ ๋๋ง ๋์ด์ผ ํฉ๋๋ค.
- ์ถฉ๋์ ์ง์ํ๋ ํ์ผ๋ค์ ๋ํ์ฌ ํ์ผ ์์ค์ ์ถฉ๋ ๊ทธ๋ฃน์ด ์์น ๋์๋์ง ํ์ธํ์ธ์.
- ์ถ๊ฐํ ์ถฉ๋ ์ค๋ธ์ ํธ ์ปดํฌ๋ํธ์ ํ์ ์ Static์ผ๋ก ์ค์ ํ์ธ์.
- Group๊ณผ Mask ์์ฑ์ ์ค์ ํ์ธ์.
- ํ์ผ์ ์ฌ์ฉํ์ฌ ์ถฉ๋์ํค๋ ค๋ ์ถฉ๋ ์ค๋ธ์ ํธ์ Group๊ณผ Mask ์์ฑ๊ฐ์ ํ์ธํ์ธ์.
Collision messages
๋ ์ค๋ธ์ ํธ๊ฐ ์ถฉ๋ํ๋ฉด, ์์ง์ ๋ ์ค๋ธ์ ํธ์ ์ปดํฌ๋ํธ ๋ชจ๋์๊ฒ ๋ฉ์ธ์ง๋ฅผ ๋ธ๋ก๋์บ์คํธ ํฉ๋๋ค.
collision_response
์ด ๋ฉ์ธ์ง๋ ๋ชจ๋ ์ถฉ๋ ์ค๋ธ์ ํธ์ ๋ํด ์ ์ก๋๋ฉฐ ์๋์ ํ๋๋ฅผ ์ค์ ํฉ๋๋ค.
other_id
์ถฉ๋ ์ค๋ธ์ ํธ๊ฐ ์ถฉ๋ํ ์๋ ์ธ์คํด์ค์ ์์ด๋ (hash)
other_position
์ถฉ๋ ์ค๋ธ์ ํธ๊ฐ ์ถฉ๋ํ ์๋ ์ธ์คํด์ค์ ์๋ ์ขํ (vector3)
group
์๋ ์ถฉ๋ ์ค๋ธ์ ํธ์ ์ถฉ๋ ๊ทธ๋ฃน (hash)
collision_response ๋ฉ์ธ์ง๋ ์ค๋ธ์ ํธ์ ์ค์ ๊ต์ฐจ๊ตฌ๊ฐ(intersection)์ ๋ํด ์์ธํ ์ ๋ณด๊ฐ ํ์ ์๋ ์ถฉ๋์ ํด๊ฒฐํ๋๋ฐ ์ ํฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์ด์์ด ์ ์ ๋ง์ท์์ ๊ฐ์งํ๋ ค๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ๊ฐ ํ๋ ์๋ง๋ค ์ถฉ๋ํ๋ ์ค๋ธ์ ํธ ์(pair)์ ์ํด ๋ฉ์ธ์ง ์ค ํ๋๋ง ์ ์ก๋ฉ๋๋ค.
contact_point_response
์ด ๋ฉ์ธ์ง๋ ์ถฉ๋ํ๋ ์ค๋ธ์ ํธ ์ค ํ๋๊ฐ Dynamic ์ด๊ฑฐ๋ Kinematic์ผ ๊ฒฝ์ฐ ์ ์ก๋๋ฉฐ ์๋์ ํ๋๋ฅผ ์ค์ ํฉ๋๋ค.
position
์ถฉ๋ ์ง์ (contact point)์ ์๋ ํฌ์ง์ (vector3)
normal
์๋ ์ค๋ธ์ ํธ์์ ํ์ฌ ์ค๋ธ์ ํธ๋ฅผ ํฅํ ์ถฉ๋ ์ง์ (contact point)์ ์๋ ๊ณต๊ฐ(world space)์์์ ๋ฒ์ (vector3)
relative_velocity
์๋ ์ค๋ธ์ ํธ์์ ๊ด์ฐฐ๋ ์ถฉ๋ ์ค๋ธ์ ํธ์ ์๋์๋ (vector3)
distance
์ค๋ธ์ ํธ๊ฐ์ ๊ฑฐ๋ฆฌ(์์(+)๋ก ๋ number)
applied_impulse
์ ์ด์ด ์ผ์ผํจ ์ถฉ๊ฒฉ๋ (number)
life_time
์ ์ด์ ์๋ช (ํ์ฌ ์ฌ์ฉ๋์ง ์์!) (number)
mass
ํ์ฌ ์ถฉ๋ ์ค๋ธ์ ํธ์ kg ์ง๋ (number)
other_mass
์๋ ์ถฉ๋ ์ค๋ธ์ ํธ์ kg ์ง๋ (number)
other_id
์๋ ์ถฉ๋ ์ค๋ธ์ ํธ์ ์ธ์คํด์ค ์์ด๋ (hash)
other_position
์๋ ์ถฉ๋ ์ค๋ธ์ ํธ์ ์๋์ขํ (vector3)
group
์๋ ์ถฉ๋ ์ค๋ธ์ ํธ์ ์ถฉ๋ ๊ทธ๋ฃน (hash)
์ค๋ธ์ ํธ๋ฅผ ์๋ฒฝํ๊ฒ ๋ถ๋ฆฌํด์ผํ๋ ๊ฒ์์ ๊ฒฝ์ฐ, contact_point_response ๋ฉ์ธ์ง๋ ํ์ํ ๋ชจ๋ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. ํ์ง๋ง ์ถฉ๋ ์(collision pair)์ด ์ฃผ์ด์ง๋ฏ๋ก, ํ๋ ์ ๋ง๋ค ๋ค์์ contact_point_response ๋ฉ์ธ์ง๊ฐ ์์ ๋ ์ ์์ต๋๋ค.
Triggers
ํธ๋ฆฌ๊ฑฐ๋ ๊ฐ๋ฒผ์ด ์ถฉ๋ ์ค๋ธ์ ํธ์ ๋๋ค. ํธ๋ฆฌ๊ฑฐ์ ์ถฉ๋ํ๋ฉด collision_response ๋ฉ์ธ์ง๊ฐ ์ ์ก๋ฉ๋๋ค. ๊ฒ๋ค๊ฐ ํธ๋ฆฌ๊ฑฐ๋ ์ถฉ๋์ด ์์(begin)๋์๊ฑฐ๋ ๋(end)๋ฌ์ ๊ฒฝ์ฐ ํน๋ณํ trigger_response ๋ํ ์ ์กํฉ๋๋ค. ์ด ๋ฉ์ธ์ง์๋ ์๋ ํ๋๊ฐ ์์ต๋๋ค.
other_id
์ถฉ๋ ์ค๋ธ์ ํธ๊ฐ ์ถฉ๋ํ ์ธ์คํด์ค์ ์์ด๋ (hash)
enter
์ํธ์์ฉ์ ์์ํ๋ค๋ฉด true, ์ํธ์์ฉ์ ๋๋๋ค๋ฉด false.
Resolving Kinematic collisions
ํค๋ค๋งํฑ ์ถฉ๋ ์ค๋ธ์ ํธ๋ฅผ ์ฌ์ฉํ๋ฉด ์ถฉ๋์ ์ค์ค๋ก ํด๊ฒฐํ๊ณ ์นจํฌ๋ ์ค๋ธ์ ํธ๋ฅผ ์์ง์ฌ์ผ ํฉ๋๋ค. ์ค๋ธ์ ํธ์ ๋ถ๋ฆฌ๋ฅผ ๋์ถฉ ๊ตฌํํ์๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
function on_message(self, message_id, message, sender)
-- ์ถฉ๋ ๋ค๋ฃจ๊ธฐ
if message_id == hash("contact_point_response") then
local newpos = go.get_position() + message.normal * message.distance
go.set_position(newpos)
end
end
์ด ์ฝ๋๋ ์๋ ๋ฌผ๋ฆฌ ์ค๋ธ์ ํธ๊ฐ ํค๋ค๋งํฑ ์ค๋ธ์ ํธ๋ฅผ ๋ซ๊ณ ๋ค์ด์์ ๊ฒฝ์ฐ ์๋ก ๋ผ์ด๋๋ ์ฒ๋ฆฌ๋ฅผ ํ์ง๋ง, ์ด๋ ๋ง์ ๊ฒฝ์ฐ์ ๋๋ฌด ๋๊ฐ๊ฑฐ๋(overshoots) ํ๋ค๋ ค(jitter) ๋ณด์ด๊ฒ ๋ฉ๋๋ค. ํค๋ค๋งํฑ ์ค๋ธ์ ํธ๋ฅผ ์ถฉ๋๋ก๋ถํฐ ์ ์ ํ๊ฒ ์ฒ๋ฆฌํ๋ ค๋ฉด ์๋์ ๊ฐ์ ์ํฉ์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.

์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ Object A์ Object B, ๋ ๊ฐ์ contact point ๋ฉ์ธ์ง๋ฅผ ์ป์ ๊ฒ์ ๋๋ค. ์์ ๋จ์ํ ๋ถ๋ฆฌ ๊ณผ์ ์ ์คํํ๋ฉด, ์นจํฌ ๋ฒกํฐ(penetration vectors)๊ฐ ๊ฐ๊ฐ ์ถ๊ฐ๋์ด, ์๋ ์ฒ๋ผ ๋ถ๋ฆฌ๋ ๊ฒ์ ๋๋ค.

๋์ , ์ฐ๋ฆฌ๋ ์ ์ด ์ง์ (contact point)์ ๋ฐ๋ณตํ๋ฉด์ ์ด๋ฏธ ์ด์ ๋ถ๋ฆฌ(previous separation)๊ฐ ์์ ํ ํน์ ๋ถ๋ถ์ ์ผ๋ก ํด๊ฒฐ๋์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์์ ์ถฉ๋ ์์ ์์๋ Object A ์์๋ถํฐ Character Collision Shape์ ๋ถ๋ฆฌ์์ ์ ์์ํฉ๋๋ค.

์ฐ๋ฆฌ๋ Object A์ ๋ฒ์ ์ ๋ฐ๋ผ์ ์บ๋ฆญํฐ ์ค๋ธ์ ํธ๋ฅผ ์นจํฌ๊ฑฐ๋ฆฌ(์์์ ๋ถ์์ ์ ์ ํ์ดํ)๋งํผ ์ด๋์ํต๋๋ค. Object B์ ๋ฒ์ ์ ๋ฐ๋ผ ์ฐ๋ฆฌ๊ฐ ์ํํด์ผ ํ๋ ๋ง์ง๋ง ์์ง์์ด ์ด๋ฏธ ์ฒซ๋ฒ์งธ๋ก ๋ถ๋ฆฌ๋ Object A์ ๋ํ์ฌ ๋ถ๋ถ์ ์ผ๋ก ๊ฒน์ณ์ง ๊ฒ์ ์ฝ๊ฒ ์ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์๋์ ํ์ดํ(๋ น์ ์ ์ ) ๋์ ์ ๋ น์์ผ๋ก ์ฑ์์ง ํ์ดํ์ ๋ฒกํฐ๋ฅผ ๋ฐ๋ผ ๋ถ๋ฆฌ์์ ์ ํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
Object B์์ ์ด์ ์์ง์(previous movement)์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํ๋ ๊ฒ์ ๊ฐ๋จํฉ๋๋ค.

์ด ๊ฑฐ๋ฆฌ๋ Object B์ ๋ํ Object A์ ์นจํฌ๋ฒกํฐ๋ฅผ ํฌ์ํ์ฌ ๊ณ์ฐํ ์ ์์ต๋๋ค. ๋ง์ง๋ง ์ด๋(movement)์ ์ฐพ์ผ๋ ค๋ฉด ๊ทธ์ ์๋์ ์นจํฌ ๋ฐฑํฐ์์ l์ ๋นผ๋ฉด(subtract) ๋ฉ๋๋ค. ์์์ ์นจํฌ ์๊ฐ ์๋ค๋ฉด, ๋ฒกํฐ๋ก ์ค์ ์ด๋๊ฐ๋ค์ ํฉ์ฐํ๊ณ ๊ฐ ์นจํฌ๋ฒกํฐ์ ๋ํ์ฌ ์ฐจ๋ก๋๋ก ํฌ์ํ๋ฉด ๋ฉ๋๋ค. ์ ์ฒด ๊ตฌํ์ ์๋์ ๊ฐ์ต๋๋ค.
function on_message(self, message_id, message, sender)
-- ์ถฉ๋ ๋ค๋ฃจ๊ธฐ
if message_id == hash("contact_point_response") then
-- ์ถฉ๋์์ ๋ฒ์ด๋๋๋ฐ ํ์ํ ์ ๋ณด ์ป๊ธฐ
-- ์ฌ๋ฌ๋ฒ ์ถฉ๋์ง์ ์ ๋๋๋ฆฌ๋ฉด์, ๋์ ํด๊ฐ๋ฉฐ ์ด๋ํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ณ์ฐ ํด์ผํจ
if message.distance > 0 then
-- ์ฐ์ ๋์ ๋ ๋ณด์ ๊ฐ์ ์นจํฌ ๋ฒกํฐ๋ฅผ ํฌ์ํฉ๋๋ค.
local proj = vmath.project(self.correction, message.normal * message.distance)
if proj < 1 then
-- ๋์ด๊ฐ๋ฒ๋ฆฌ์ง ์๋๋ก ํฌ์ฌ(projections)์ ์ ๊ฒฝ ์ธ๊ฒ
local comp = (message.distance - message.distance * proj) * message.normal
-- ๋ณด์(compensation) ๋ฐ์ํ๊ธฐ
go.set_position(go.get_position() + comp)
-- ๋ณด์ ๊ฐ์ ๋์ ํฉ์ฐํ๊ธฐ
self.correction = self.correction + comp
end
end
end
end
Best practices
Triggers
ํธ๋ฆฌ๊ฑฐ ์ถฉ๋ ์ค๋ธ์ ํธ๋ ์ ํ์ ์ธ๊ฒ ๋ง์ต๋๋ค. ๋ง์ฝ ํ๋ ์ด์ด๊ฐ ํธ๋ฆฌ๊ฑฐ๋ก ์ด๋ํ์ ๋ ์ถฉ๋์ ๊ฐ์ฝ๊ณผ ๋น๋กํ๋ ํฌ๊ธฐ ๋งํผ์ ์๋ฆฌ๊ฐ ๋์ผ ํ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค. ์ด๋ฅผ ์ํด์๋ ํธ๋ฆฌ๊ฑฐ์ ์นจํฌํ ๊ฑฐ๋ฆฌ(penetration distance)๋ฅผ ์์๋ด์ผ ํฉ๋๋ค. ์ฌ๊ธฐ์, ์ผ๋ฐ ํธ๋ฆฌ๊ฑฐ ์ถฉ๋ ์ค๋ธ์ ํธ๋ก๋ ์ด๋ฅผ ์ฒ๋ฆฌํ ์ ์์ผ๋ฏ๋ก, ํค๋ค๋งํฑ ์ค๋ธ์ ํธ๋ฅผ ๋์ ์ฌ์ฉํ์ฌ ์ถฉ๋ ๋ฐ์ดํฐ์ ์นจํฌ๊ฑฐ๋ฆฌ๋ง ์ฌ์ฉํ๊ณ ์ถฉ๋์ ์ํ ๋ถ๋ฆฌ(separation of collisions)๋ ์ฒ๋ฆฌํ์ง ์์ผ๋ฉด ๋ฉ๋๋ค.
ํค๋ค๋งํฑ ์ค๋ธ์ ํธ๋ ํธ๋ฆฌ๊ฑฐ์ ๋นํด ์ฑ๋ฅ ๋น์ฉ์ด ๋ง์ด ๋ค๊ธฐ ๋๋ฌธ์ ํ๋ช ํ๊ฒ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
Choosing between Dynamic or Kinematic objects
ํ๋ ์ด์ด ์บ๋ฆญํฐ๊ฐ ๋ ๋ฒจ์ ๋ฐ๋ผ ์์ง์ด๋ ํ๋ซํฌ๋จธ๋ฅ์ ๊ฒ์์ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค. ์ฌ๊ธฐ์ ํ๋ ์ด์ด ์บ๋ฆญํฐ๋ฅผ Dynamic ๋ฌผ๋ฆฌ ์ค๋ธ์ ํธ๋ก, ์๋๊ฐ์ฒด๋ฅผ Static ๋ฌผ๋ฆฌ ์ค๋ธ์ ํธ๋ก ๋ง๋๋๊ฒ์ด ์ผ๋จ ์ข์ ์๊ฐ์ธ ๊ฒ ์ฒ๋ผ ๋๊ปด์ง๋๋ค. ๊ทธ๋ฆฌ๊ณ ํค ์ ๋ ฅ์ ํ๋ฉด ํ๋ ์ด์ด ์ค๋ธ์ ํธ์ ๋ค์ํ ๋ฌผ๋ฆฌ์ ํ์ ๊ฐํ๋ ๊ฒ์ผ๋ก ์์ง์์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ๊ฐ๋ฐํ๋ค ๋ณด๋ฉด ๊ตฌํ ์์ฒด๋ ๊ฐ๋ฅํ์ง๋ง ๋ฉ์ง ๊ฒฐ๊ณผ๋ฌผ์ ๋ง๋ค์ด ๋ด๊ธฐ๋ ๋งค์ฐ ์ด๋ ต์ต๋๋ค. ๊ฒ์์ ์ ์ด๊ฐ ๋์ผํ ๋ฌผ๋ฆฌ์์ง์์ ๋์ผํ ๋ฐฉ๋ฒ์ผ๋ก ์ฒ๋ฆฌ๋๋ฏ๋ก ๋ค๋ฅธ ์์ฒ๊ฐ์ง ๊ฒ์๋ค๊ณผ ๋ค๋ฅผ ๋ฐ ์๊ฒ ๋๊ปด์ง ์๋ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด ๋ฌธ์ ๋ Box2D ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์ ์ด ํ์ค๊ฐ์ ๋ดํด์ ๋ฒ์น์ ๋ฐ๋ฅธ ๋ฐ๋ฉด, ํ๋ซํฌ๋จธ ๊ฒ์์ ๋ฌผ๋ฆฌ ๋ฒ์น์ ๊ทผ๋ณธ์ ์ผ๋ก ์กฐ๊ธ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๋ฒ์ด์ง๋๋ค. ๋ดํด ๋ฐฉ์์ ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์ ์ ๋น ๋ดํด ๋ฐฉ์์ผ๋ก ๋ง๋ค๋ ค๋ฉด ๋ง์ ๋ ธ๋ ฅ์ด ํ์ํฉ๋๋ค.
์ฌ๋ฌ ๋ฌธ์ ์ค ํ๋๋ฅผ ์๋ฅผ ๋ค๋ฉด, ๊ฐ์ฅ์๋ฆฌ(edges)์์ ๋ฐ์ํ๋ ๋ฌธ์ ๊ฐ ์๋๋ฐ, ํ๋ ์ด์ด๊ฐ ํ๋ซํผ ๊ฐ์ฅ์๋ฆฌ์ ๊ฑธ์ณ์ง๋ฉด ํ์ค์ ์์์ฒ๋ผ ๋ชจ์๋ฆฌ์ ๊ฑธ์ณ ๊ธฐ์ธ์ด ์ง๊ฒ ๋ฉ๋๋ค.

์ด ๋ฌธ์ ๋ ์บ๋ฆญํฐ ์ถฉ๋ ์ค๋ธ์ ํธ์ "Locked Rotation" ์์ฑ์ ์ค์ ํด์ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด ๋ฌธ์ ์ ํต์ฌ์ ์ด ์ ํ์ ์ธ ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์ ์ ๋์ด ์ง์ ํต์ ํ๋ ค๋ฉด ๋์์ด๋๋ ํ๋ก๊ทธ๋๋จธ์ ํ์ ๋น์ด ์บ๋ฆญํฐ๋ฅผ ์์ง์ด๋ ๊ฒ์ด ๋ซ๋ค๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ฌ๋ฏ๋ก ํ๋ ์ด์ด ์บ๋ฆญํฐ๋ฅผ ํค๋ค๋งํฑ ๋ฌผ๋ฆฌ ์ค๋ธ์ ํธ๋ก ๊ตฌํํ๋๊ฒ์ ๊ฐ๋ ฅํ ์ถ์ฒ๋๋ฆฝ๋๋ค. ๋ฌผ๋ฆฌ ์์ง์ ์ถฉ๋์ ๊ฐ์งํ๊ณ ์ฒ๋ฆฌํ๊ณ ์ถฉ๋ํ ์ค๋ธ์ ํธ๋ค์ ๋ถ๋ฆฌํ๋๋ฐ ํ์ํ ๋งํผ๋ง ์ฌ์ฉํ์ญ์์ค. ์ด๋ฌํ ์ ๊ทผ ๋ฐฉ์์ ์ด๋ฐ์ ๋ง์ ์์ ์ด ํ์ํ์ง๋ง, ๋์ค์๋ ํ๋ ์ด์ด์ ๊ฒฝํ์ ๋ญ๊ฐ ๋ ๋ฉ์ง๊ณ ๊ฐ์ฑ์๊ฒ ํ๋ํ ์ ์์ต๋๋ค.
(๊ทธ๋ํฝ ์์ ์ผ๋ถ๋ Kenney: http://kenney.nl/assets ๊ฐ ์ ์ํ์ต๋๋ค.)