물리엔진
현실 세계의 물리 법칙들을 3D 공간에서 실현해 주는 엔진
→ React Three Fiber(R3F)에서 Rapier라는 물리엔진을 사용할 수 있게 해주는 React3 Rapier 라이브러리 사용
@react-three/rapier 패키지 설치
npm install @react-three/rapier
기본적인 물리 설정
- Suspense
비동기로 로딩되는 컴포넌트들이 모두 로딩될 때까지 기다렸다가 렌더링 - Physics
물리 법칙이 적용되는 공간을 정의 - RigidBody
실제로 물체가 물리적으로 상호작용하도록 설정
import { Suspense } from "react";
import { Physics, RigidBody } from "@react-three/rapier";
<Suspense>
<Physics>
<RigidBody>
<ZooMap />
</RigidBody>
</Physics>
</Suspense>
RigidBody 적용
- ZooMap(배경 맵)은 움직이지 않도록 Fixed 설정
- Animal과 Dino는 충돌 감지를 위해 colliders="hull" 적용
- Animal, Dino Objects 넘어지는 것을 방지 → lockRotations 속성 추가 혹은 enabledRotations속성 값 false로 설정
<Suspense>
<Physics>
{/* 맵을 고정된 물체로 설정 */}
<RigidBody type="fixed" colliders="trimesh">
<ZooMap />
</RigidBody>
{/* 알파카 객체 */}
<RigidBody lockRotations colliders="hull">
<Animal name="Alpaca" position={[-15, 20, 0]} />
</RigidBody>
{/* 티라노사우르스 객체 */}
<RigidBody enabledRotations={[false, false, false]} colliders="hull">
<Dino name="Triceratops" position={[10, 20, 0]} />
</RigidBody>
</Physics>
</Suspense>
물리 엔진 디버깅
<Physics debug>
...
</Physics>
물리 법칙 적용 확인용 디버깅 모드 활성화 후 비활성화 (성능이 저하됨)
Collider 설정
Collider
물체와 충돌하는 범위 설정
ball | 구형 충돌 감지 |
cuboid | 직육면체 충돌 감지 |
hull | 실제 메쉬의 경계선을 따라 충돌 감지 |
trimesh | 삼각형 메쉬 기반 충돌 감지 (주로 지형에 사용) |
배경(Map)에는 trimesh 사용
동물(Animal, Dino)에는 hull 사용
객체 회전 방지 (lockRotations)
<RigidBody lockRotations colliders="hull">
<Animal name="Alpaca" position={[-15, 20, 0]} />
</RigidBody>
<RigidBody enabledRotations={[false, false, false]} colliders="hull">
<Dino name="Triceratops" position={[10, 20, 0]} />
</RigidBody>
lockRotations → 회전을 완전히 고정
enabledRotations → 특정 축에서만 회전 가능하도록 설정 ([false, false, false]는 모든 축에서 회전 금지)
그리드 헬퍼 추가
객체 위치 조정
<gridHelper rotation={[Math.PI / 2, 0, 0]} args={[500, 50]} />
최종 참고 코드
import { OrbitControls } from "@react-three/drei";
import { Animal } from "./Animal";
import { ZooMap } from "./ZooMap";
import { Dino } from "./Dino";
import { Suspense } from "react";
import { Physics, RigidBody } from "@react-three/rapier";
const START_Y = 20;
export const Environments = () => {
return (
<>
{/* 그리드 헬퍼 */}
<gridHelper rotation={[Math.PI / 2, 0, 0]} args={[500, 50]} />
<ambientLight intensity={4} />
<directionalLight intensity={4} position={[3, 3, 3]} />
<OrbitControls />
<Suspense>
<Physics>
{/* 맵을 고정된 물체로 설정 */}
<RigidBody type="fixed" colliders="trimesh">
<ZooMap />
</RigidBody>
{/* 알파카 객체 */}
<RigidBody lockRotations colliders="hull">
<Animal name="Alpaca" position={[-15, START_Y, 0]} />
</RigidBody>
{/* 티라노사우르스 객체 */}
<RigidBody enabledRotations={[false, false, false]} colliders="hull">
<Dino name="Triceratops" position={[10, START_Y, 0]} />
</RigidBody>
</Physics>
</Suspense>
</>
);
};
'React > ReactThreeFiber' 카테고리의 다른 글
Edit Mode 구현 (2) - 상태 관리 내 데이터 추가, 컴포넌트 물리엔진 적용, Edit Mode에서의 Object 이동, UI 크기 조정과 시각화 개선 (0) | 2025.03.15 |
---|---|
Edit Mode 구현 (1) - 모드 변경 GUI, 상태 관리 시스템 구축 (0) | 2025.03.14 |
오브젝트 위치 조정 및 애니메이션 적용 (0) | 2025.03.14 |
3D 오브젝트 불러오기 (0) | 2025.03.14 |
useContext (0) | 2025.03.14 |