TECH3

LET'S GET PHYSICAL​​

07                                        2025-2026

In dit onderdeel duiken we dieper in de physics laag van React Three Fiber. We leren hoe we echte fysica kunnen integreren - massa, rigid bodies, constraints, collision responses - en hoe we dat declaratief kunnen doen. Dit allemaal door React Three Rapier.

LET'S GET PHYSICAL!

RAPIER

01

01

RAPIER

WHAT?

React Three Rapier is de officiële physics integratie voor React Three Fiber.
Het maakt het mogelijk om declaratief echte 3D physics toe te voegen in R3F scenes, zonder WebGL boilerplate.

  • ondersteunt rigid bodies, colliders, constraints, joints, sensors, impulses

  • extreem snel dankzij native Rust physics (sneller dan Cannon / Ammo engines)

  • volledig React gedreven: hooks, components, lifecycle events

  • ideaal voor product configurators, games, AR commerce en simulatie

  • stabiele collisions, stacking en sleeping (geen jank / drift)

  • werkt soepel samen met controls en interactieve UI flows, blijft volledig in sync met React state

01

RAPIER

STARTER

We starten met een basis scene zonder bijzondere eigenschappen. De gepresenteerde concepten zijn echter van toepassing op alle 3D-modellen en -omgevingen.

npm install @react-three/rapier

Eens je de starter file gestart hebt voer je volgende uit in de terminal.

Rapier is succesvol geïnstalleerd, waardoor we nu physics-functionaliteit kunnen toepassen.

01

RAPIER

PHYSICS

De Physics-component identificeert objecten die actief deelnemen aan de physics-simulatie. Objecten buiten deze component blijven statisch en hebben geen invloed op de simulatie.

import { Physics } from '@react-three/rapier'

<Physics>
     <group>
         <Sphere position-x={-2} position-y={2} scale={1} />     
         <Box ref={cubeRef} rotation-y={Math.PI * 0.25} position-x={2} scale={1.5}/> 
     </group> 

     {/* Floor */}
     <Ground position-y={- 1} rotation-x={- Math.PI * 0.5} scale={10}/>      
</Physics>

Importeer de Physics-component uit Rapier en omsluit onze drie meshes hiermee.

01

RAPIER

RIGIDBODY

Zodra de Physics-“World” rond de meshes is opgezet, kunnen we specificeren welke objecten door de physics beïnvloed worden door een RigidBody rondom elk object te plaatsen.

import { RigidBody, Physics } from '@react-three/rapier'

<Physics>
   <RigidBody>
      <Sphere position-x={-2} position-y={2} scale={1} />     
   </RigidBody>

    {/* ... */}
</Physics>

Importeer de RigidBody-component en omsluit de geselecteerde mesh hiermee.

De sphere valt door de grond... waarom is dit het geval?

01

RAPIER

RIGIDBODY

Het is noodzakelijk een RigidBody rond de plane te plaatsen om interactie tussen de objecten mogelijk te maken.

<RigidBody>
     <Sphere position-x={-2} position-y={2} scale={1} />     
</RigidBody>

Zet de Ground in een RigidBody en zie wat er gebeurt in de simulatie.

Zie je dat de vloer meebeweegt met de sphere? Dat willen we niet. Geef de RigidBody van de vloer het type ‘fixed’ om dit te fixen.

<RigidBody type="fixed">
      <Ground position-y={- 1} rotation-x={- Math.PI * 0.5} scale={10}/>
</RigidBody>

01

RAPIER

WHAT HAPPENS?

Het integreren van physics via React Three Rapier is eenvoudig. Houd rekening met de volgende aandachtspunten:

  • Het is niet nodig de physics bij elk frame te updaten.

  • Objecten zijn automatisch geassocieerd met hun respectieve RigidBody.

  • Rapier genereert physics-shapes die overeenkomen met de Three.js-objecten.

  • Specificatie van eigenschappen zoals oppervlak, massa of zwaartekracht is niet vereist.

Let op: HMR pakt niet altijd alle wijzigingen. Ververs de pagina soms, want complexe physics kan kleine glitches veroorzaken.

01

RAPIER

DEBUGGING

Wil je de physics beter begrijpen? Zet de debug-property op Physics en zie welke objecten botsen en op welke manier. Let op: gebruik debug alleen tijdelijk, het kan de performance drukken.

<Physics debug>

    {/* ... */}

</Physics>

Activeer debug op het Physics component

LET'S GET PHYSICAL!

COLLIDERS

02

02

COLLIDERS

COLLIDER

Colliders definiëren de geometrische vorm van een RigidBody. Voor de sphere wordt een cube gebruikt, aangeduid als een ‘cuboid’ collider, wat de standaard is voor alle RigidBodies in Rapier.

Plaats een cuboidCollider rond de box door hem in de RigidBody te zetten.

<RigidBody>
    <Box ref={cubeRef} rotation-y={Math.PI * 0.25} position-x={2} position-y={2} scale={1.5}/> 
</RigidBody>

Verander de schaal van de mesh en kijk of de collider correct meebeweegt.

<RigidBody>
    <Box ref={cubeRef} rotation-y={Math.PI * 0.25} position-x={2} position-y={2} scale={3}/> 
</RigidBody>

02

COLLIDERS

COLLIDER

Wanneer de cube wordt aangepast naar een rechthoek, zal de standaard cuboidCollider zich automatisch optimaliseren om de mesh-vorm te volgen.

Pas de args van je boxGeometry aan om de box in een rechthoek te veranderen.

<RigidBody>
    <mesh castShadow position={ [ 2, 2, 0 ] }>
        <boxGeometry args={ [ 3, 2, 1 ] } />
        <meshStandardMaterial color="mediumpurple" />
    </mesh>
</RigidBody>

02

COLLIDERS

COMPOSED

Een RigidBody kan meerdere colliders bevatten. Bij toevoeging van een tweede mesh genereert de RigidBody automatisch een collider die optimaal overeenkomt met de nieuwe mesh.

Voeg een mesh toe aan de Box component.

<RigidBody>
   <mesh {...props}>
        <boxGeometry />
        <meshStandardMaterial color={color || "royalblue"}/>
    </mesh>
    <mesh>
        <boxGeometry args={[3,2,1]}/>
        <meshStandardMaterial color={color || "royalblue"}/>
    </mesh>
</RigidBody>

02

COLLIDERS

COMPOSED

Wanneer de tweede mesh wordt verplaatst, beïnvloedt dit het zwaartepunt van het object. De RigidBody verwerkt automatisch de invloed van beide colliders.

Verander de positie van de tweede box.

<RigidBody>
    <mesh {...props}>
        <boxGeometry />
        <meshStandardMaterial color={color || "royalblue"}/>
    </mesh>
    <mesh position-z={-2}>
        <boxGeometry  args={[3,2,1]}/>
        <meshStandardMaterial color={color || "royalblue"}/>
    </mesh>
</RigidBody>

02

COLLIDERS

BALL COLLIDER

De huidige collider van de sphere is niet optimaal. In veel gevallen beïnvloedt dit de simulatie niet, tenzij nauwkeurigheid vereist is of het visueel relevant is. Cuboid-colliders zijn bovendien performanter. Je kan wel de collider van de RigidBody aanpassen.

Verander de collider op de RigidBody naar 'ball'

<RigidBody colliders="ball">
    <Sphere position-x={-2} position-y={4} scale={1} />     
</RigidBody>

02

COLLIDERS

HULL COLLIDER

Bij een Torus zijn cuboid- of ball-colliders niet geschikt. Een hull-collider volgt de contouren van het object zo nauwkeurig mogelijk, waarbij interne gaten worden genegeerd.

Verander onze box naar een Torus met een Hull Collider

<RigidBody colliders="hull">
    <mesh castShadow position={ [ 0, 1, - 0.25 ] } rotation={ [ Math.PI * 0.1, 0, 0 ] }>
        <torusGeometry args={ [ 1, 0.5, 16, 32 ] } />
        <meshStandardMaterial color="mediumpurple" />
    </mesh>
</RigidBody>

02

COLLIDERS

TRIMESH

Wil je perfecte matching met je model? Gebruik dan een Trimesh-collider. Deze volgt alle contouren en maakt een collider die precies past.

Verander de collider naar trimesh

<RigidBody colliders="trimesh">
    <mesh castShadow position={ [ -2, 1, - 0.25 ] } rotation={ [ Math.PI * 0.1, 0, 0 ] }>
        <torusGeometry args={ [ 1, 0.5, 16, 32 ] } />
        <meshStandardMaterial color="mediumpurple" />
    </mesh>
</RigidBody>

Let op: hull- en trimesh-colliders zijn zwaar en vragen veel berekeningen. Gebruik ze alleen als het echt moet. Ze zijn ook gevoeliger voor glitches bij snelle bewegingen.

LET'S GET PHYSICAL!

CUSTOM COLLIDERS

03

03

CUSTOM COLLIDERS

CUSTOM

Rapier biedt meerdere standaard-colliders, maar je kunt ook zelf custom colliders bouwen.

03

CUSTOM COLLIDERS

CUBOID

We zullen nu custom colliders creëren en testen. Schakel de standaard-colliders op de RigidBody uit door deze op false te zetten en importeer de benodigde collider vanuit Rapier.

Plaats de collider op false en voeg je eigen CuboidCollider toe.

import { CuboidCollider, RigidBody, Physics } from '@react-three/rapier'

<RigidBody colliders={ false }>
    <CuboidCollider args={ [ 1, 1, 1 ] } />
    {/* ... */}
</RigidBody>

Onze kubus is een beetje off. Geen probleem: verander gewoon de grootte, positie en rotatie van de RigidBody.

<RigidBody colliders={false}  position-x={2} position-y={2} scale={1.5}>
     <CuboidCollider args={[.75,.75,.75]} />
     <Box ref={cubeRef}  scale={1.5}/> 
</RigidBody>

03

CUSTOM COLLIDERS

MULTIPLE

Het is mogelijk om meerdere colliders in één RigidBody te definiëren zonder extra meshes. Dit wordt bereikt door een aanvullende CuboidCollider toe te voegen.

Voeg een tweede CuboidCollider toe aan de RigidBody

<RigidBody colliders={ false } position={ [ 0, 1, - 0.25 ] } rotation={ [ Math.PI * 0.1, 0, 0 ] }>
    <CuboidCollider args={ [ 1.5, 1.5, 0.5 ] } />
    <CuboidCollider args={ [ 1, 1, 1 ] } />
    {/* ... */}
</RigidBody>

03

CUSTOM COLLIDERS

BALL

Je kunt in plaats van een Cuboid een Ball Collider gebruiken. Dit creëert een sphere rond het object en functioneert correct binnen de RigidBody.

Importeer de BallCollider en vervang de 2 CuboidColliders door 1 Ball Collider

<RigidBody colliders={false} position-x={2} position-y={2} scale={1.5}>
    <BallCollider args={ [ 1.5 ] } />
    {/* ... */}
</RigidBody>

Naast de standaard-colliders zijn er nog andere types die je zelf kunt toevoegen. Je kunt kiezen tussen handmatig plaatsen of automatisch laten genereren.
Meer info? Bekijk de docs

LET'S GET PHYSICAL!

FORCES

04

04

FORCES

FORCES

Onze RigidBodies vallen nu vanzelf, maar we kunnen ze ook beïnvloeden met ‘forces’. In dit voorbeeld laten we een kubus springen als we erop klikken.

We plaatsen onze scene terug naar het begin.

<RigidBody colliders="ball">
     <Sphere position-x={-2} position-y={2} scale={1} />     
</RigidBody>
<RigidBody>
     <Box ref={cubeRef} position-x={2} position-y={2} scale={1.5}/> 
</RigidBody>

04

FORCES

FORCES

Om krachten op de kubus te zetten, maken we eerst een reference. Voeg daarnaast een onClick-functie toe die de kubus activeert bij klikken.

Maak een cubeRef aan en plaats deze op de kubus.

import { useRef } from 'react'

export default function Experience()
{
    const cubeRef = useRef()
}

Voeg de reference op de RigidBody

<RigidBody ref={ cube } position={ [ 1.5, 2, 0 ] }>
    {/* ... */}
</RigidBody>

04

FORCES

FORCES

Maak een cubeJump function aan en zend deze naar de cube.

const cube = useRef()
const cubeJump = () =>
{
    console.log('jump!')
}

Voeg de reference op de RigidBody

<RigidBody ref={ cube } position={ [ 1.5, 2, 0 ] }>
    <mesh castShadow onClick={ cubeJump }>
        {/* ... */}
    </mesh>
</RigidBody>

Kijk nu eens wat er in de current reference zit in de console.

const cubeJump = () =>
{
    console.log(cube.current)
}

04

FORCES

IMPULSE

Plaats een applyImpulse op de kubus-reference in de cubeJump-functie om de sprong te simuleren.

const cubeJump = () =>
{
    cube.current.applyImpulse({ x: 0, y: 10, z: 0 })
}

Je kan forces toepassen via addForce of applyImpulse. addForce werkt langzaam, zoals wind. applyImpulse is een korte stoot, perfect voor een sprongetje.

04

FORCES

TORQUE

Voeg een applyTorqueImpulse op de reference in onze cubeJump function.

const cubeJump = () =>
{
    cubeRef.current.applyImpulse({ x: 0, y: 10, z: 0 })
    cubeRef.current.applyTorqueImpulse({ x: 0, y: 1, z: 0 })
}

Onze kubus beweegt nu alleen omhoog. Wil je dat hij ook draait bij een tik? Gebruik addTorque voor continue draaiing of applyTorqueImpulse voor een korte draai-impuls.

Gooi die torque lekker random over alle assen, dan ziet het er realistischer uit.

const cubeJump = () =>
{
   cubeRef.current.applyImpulse({ x: 0, y: 15, z: 0 })
   cubeRef.current.applyTorqueImpulse({ x: (Math.random() * 5) - 0.5, y: (Math.random() * 5) - 0.5, z: (Math.random() * 5) - 0.5 })
}

04

FORCES

USE THE FORCE

Nu kan je met forces spelen in React Three Rapier. Met deze trucs maak je je scene meteen een stuk leuker en interactiever. May the force be with you!

LET'S GET PHYSICAL!

OBJECT SETTINGS

05

SETTINGS

Er bestaan diverse manieren om het gedrag van objecten en hun onderlinge interacties te beheersen, zoals wrijving, restitutie, massa, zwaartekracht, posities, bewegingsrichtingen, en andere parameters.

Laten we eens kijken naar een paar belangrijke eigenschappen die je kunt aanpassen:

05

OBJECT SETTINGS

  • Gravity
  • Restitution
  • Friction
  • Mass
  • Position & rotation

GRAVITY

De standaardinstelling voor zwaartekracht is -9.81 om aardse omstandigheden te simuleren. Deze waarde kan worden aangepast via een Vector3-array toegewezen aan de gravity-eigenschap.

Verander de gravity naar die van de maan (-1.62).

05

OBJECT SETTINGS

<Physics debug gravity={ [ 0, - 1.62, 0 ] }>

Klik op de cube en je ziet dat hij hoger springt en trager valt. Experimenteer ook met het omkeren van de zwaartekracht of het toepassen op verschillende assen.

<Physics debug gravity={ [ 0, 1.62, 0 ] }>
<Physics debug gravity={ [ - 1.62, 0, 0 ] }>

GRAVITY SCALE

De gravityScale-eigenschap geeft aan in welke mate de zwaartekracht van toepassing is op een RigidBody. De standaardwaarde is 1.

Verander de gravityScale van de cube naar 0.2

05

OBJECT SETTINGS

<RigidBody ref={ cube } position={ [ 1.5, 2, 0 ] } gravityScale={ 0.2 }>
    {/* ... */}
</RigidBody>

Gooi er een negatieve waarde in en je object gaat omhoog in plaats van omlaag.

<RigidBody ref={ cube } position={ [ 1.5, 2, 0 ] } gravityScale={ - 0.2 }>
    {/* ... */}
</RigidBody>

Deze aanpassing is praktisch in scenario’s waarin verschillende gebieden in de scene verschillende zwaartekrachteffecten vereisen.

RESTITUTION

De objecten volgen de zwaartekracht, maar vertonen geen stuiterend gedrag. De restitution-eigenschap regelt de veerkracht; de standaardwaarde is 0.

Zet een restitution van 1 op de cube en zie wat gebeurd.

05

OBJECT SETTINGS

<RigidBody
    ref={ cube }
    position={ [ 1.5, 2, 0 ] }
    gravityScale={ 1 }
    restitution={ 1 }
>
    {/* ... */}
</RigidBody>

RESTITUTION

De kubus stuitert, maar bereikt niet de startpositie. Voeg een restitution-waarde toe aan de vloer toe om dit te corrigeren. Hard oppervlak vs. zacht oppervlak beïnvloedt de bounce.

Pas de restitution van de floor aan naar 1 en observeer het effect. (Bouncy Castle)

05

OBJECT SETTINGS

<RigidBody
    ref={ cube }
    position={ [ 1.5, 2, 0 ] }
    gravityScale={ 1 }
    restitution={ 1 }
>
    {/* ... */}
</RigidBody>

<RigidBody type="fixed" restitution={ 1 }>
    {/* ... */}
</RigidBody>

FRICTION

De friction-eigenschap bepaalt de weerstand tussen oppervlakken. Een hogere waarde veroorzaakt snellere afremming, terwijl een lagere waarde langere bewegingen mogelijk maakt. Standaard: 0.7.

Vooraleer we dit doen zullen we eerst de resitution terug op 0 plaatsen van de floor.

05

OBJECT SETTINGS

<RigidBody
    ref={ cube }
    position={ [ 1.5, 2, 0 ] }
    gravityScale={ 1 }
    restitution={ 0 }
>
    {/* ... */}
</RigidBody>

<RigidBody type="fixed" restitution={ 0 }>
    {/* ... */}
</RigidBody>

FRICTION

Verander de friction van beide objecten op 0 en kijk wat er gebeurt.

05

OBJECT SETTINGS

<RigidBody
    ref={ cube }
    position={ [ 1.5, 2, 0 ] }
    gravityScale={ 1 }
    restitution={ 0 }
    friction={ 0 }
>
    {/* ... */}
</RigidBody>

<RigidBody
    type="fixed"
    restitution={ 0 }
    friction={ 0 }
>
    {/* ... */}
</RigidBody>

Klik op het object om te springen en observeer het effect. Cool!
Pas daarna de friction aan naar 0.7 of verwijder deze.

MASS

05

OBJECT SETTINGS

<RigidBody
    ref={ cube }
    position={ [ 1.5, 2, 0 ] }
    gravityScale={ 1 }
    restitution={ 0 }
    friction={ 0.7 }
    colliders={ false }
    position-x={2} 
    position-y={2}
>
    {/* ... */}
    <CuboidCollider args={ [ 1, 1, 1 ] }  />
    <Box onClick={cubeJump} scale={2}/> 
</RigidBody>

De massa van een RigidBody wordt bepaald door de geometrie en het volume van het object. Grotere massa verhoogt de impact bij botsingen, maar verandert de valversnelling niet.

Voor het aanpassen van de massa dient het object te zijn voorzien van een collider. Hier gebruiken we een CuboidCollider.

MASS

05

OBJECT SETTINGS

<CuboidCollider mass={ 0.5 } args={ [ 0.5, 0.5, 0.5 ] } />

De massa kan worden aangepast via het mass-attribuut van de betreffende collider.

Pas de mass aan naar 0.5 en klik eens op het object.

<CuboidCollider mass={ 2 } args={ [ 0.5, 0.5, 0.5 ] } />

Pas de mass aan naar 2 en klik eens op het object.

ACCESS MASS

05

OBJECT SETTINGS

const cubeJump = () =>
{
    const mass = cube.current.mass()
    console.log(mass)

}

Omdat onze massa nu hoger is, is de kracht van de toegepaste impulse niet sterk genoeg. Voor leerdoeleinden willen we de kracht van de impulse aanpassen, zodat het object ongeacht de massa even hoog springt.
Hiervoor moeten we de massa uit onze reference halen.

In onze cubeJump-functie halen we de massa uit de reference.

const cubeJump = () =>
{
    const mass = cube.current.mass()
    cube.current.applyImpulse({ x: 0, y: 10 * mass, z: 0 })
}

Vermenigvuldig de impulse met de massa om de kracht aan te passen

POSITION & ROTATION

05

OBJECT SETTINGS

Op onze RigidBody kunnen we ook de positie en rotatie aanpassen, zoals we eerder hebben gezien.
Let op: bij dynamische en fixed objecten mag je deze waarden tijdens runtime niet veranderen, omdat dit ongewenst gedrag kan veroorzaken.
Als je tijdens runtime updates nodig hebt, gebruik dan kinematic types.

LET'S GET PHYSICAL!

TYPES

06

KINEMATIC

We hebben het fixed type gezien voor de ground en het dynamic type voor objecten zoals de Ball en Cube. Er is echter nog een derde type: kinematic. Dit type gebruik je vooral als je iets tijdens runtime wilt bewegen of roteren.

Creëer een lange box die we gaan gebruiken als een draaiende balk in de scene.

06

TYPES

<Physics debug gravity={ [ 0, - 9.81, 0 ] }>

    {/* ... */}
    <RigidBody
        position={ [ 0, - 0.8, 0 ] }
        friction={ 0 }
        type="kinematicPosition"
    >
        <mesh castShadow scale={ [ 0.4, 0.4, 4 ] }>
            <boxGeometry />
            <meshStandardMaterial color="red" />
        </mesh>
    </RigidBody>
</Physics>

KINEMATIC

We gaan de positie handmatig aanpassen, dus hebben we een reference naar ons object nodig.

Creëer een reference en voeg deze toe aan de RigidBody van de draaiende balk.

06

TYPES

export default function Experience()
{
    const spinnerRef = useRef()
	
    <RigidBody
    ref={ spinnerRef }
    position={ [ 0, - 0.8, 0 ] }
    friction={ 0 }
    type="kinematicPosition"
>
    {/* ... */}
</RigidBody>
   
}

KINEMATIC

We zullen onze balk elke seconde aanpassen. Hier moet meteen een belletje rinkelen: dit is een perfect moment om useFrame te gebruiken.

Importeer useFrame en haal de state ervan op.

06

TYPES

import { useFrame } from '@react-three/fiber'

export default function Experience()
{
    useFrame((state) =>
    {
        
    })
}

We halen onze tijd op via de clock om onze balk te laten draaien a.d.h.v de tijd.

const time = state.clock.getElapsedTime()
console.log("Time:", time)

KINEMATIC

Voor het aanpassen van rotatie en positie van een kinematic object dienen de methodes setNextKinematicRotation en setNextKinematicTranslation te worden gebruikt. Omdat rotatie in quaternion-vorm vereist is, wordt een Euler-conversie uitgevoerd.

Importeer THREE en plaats volgende code in de useFrame

06

TYPES

import * as THREE from 'three'

useFrame((state) =>
{
    const time = state.clock.getElapsedTime()

    const eulerRotation = new THREE.Euler(0, time, 0)
    const quaternionRotation = new THREE.Quaternion()
    quaternionRotation.setFromEuler(eulerRotation)
})

KINEMATIC

Zet de Kinematic Rotation van de ref op de rotatie die we hebben klaargemaakt.

06

TYPES

useFrame((state) =>
{
    const time = state.clock.getElapsedTime()

    const eulerRotation = new THREE.Euler(0, time, 0)
    const quaternionRotation = new THREE.Quaternion()
    quaternionRotation.setFromEuler(eulerRotation)
    twister.current.setNextKinematicRotation(quaternionRotation)
})

De balk draait nu ... wil je deze sneller? Vermenigvuldig dan de tijd met een groter getal.

useFrame((state) =>
{
    const time = state.clock.getElapsedTime()

    const eulerRotation = new THREE.Euler(0, time * 4, 0)
})

KINEMATIC

06

TYPES

Maak een angle aan a.d.h.v de tijd en gebruik deze om de cos en sin te berekenen.

useFrame((state) =>
{
    const angle = time * 0.5
    const x = Math.cos(angle)
    const z = Math.sin(angle)
})

Nu gaan we de positie aanpassen zodat onze balk rond de vloer in een cirkel draait. Hiervoor gebruiken we functies zoals cos voor de x-as en sin voor de z-as.

Nu kan je makkelijk de translation aanpassen door deze aan de  x en z mee te geven.

useFrame((state) =>
{
    // ...
    twister.current.setNextKinematicTranslation({ x: x, y: - 0.8, z: z })
})

Wil je een grotere cirkel? Vermenigvuldig gewoon een groter getal bij de cos en sin.

LET'S GET PHYSICAL!

EVENTS

07

EVENTS

We kunnen luisteren naar bepaalde events op onze RigidBodies, wat het interessant maakt om reacties te programmeren op basis van deze events.

De events die je kunt gebruiken:

  • onCollisionEnter – wordt getriggerd bij aanraking.

  • onCollisionExit – wordt getriggerd bij het verlaten van contact.

  • onSleep – start als de RigidBody een tijd geen contact heeft.

  • onWake – start wanneer de RigidBody weer actief contact maakt.

07

EVENTS

Laten we elk event stap voor stap onderzoeken om te begrijpen hoe ze werken.

ENTER

We zullen ervoor zorgen dat er een klein geluidje wordt afgespeeld wanneer een collision plaatsvindt met een bepaald object.

Implementeer een collisionEnter-functie in de Experience en wijs deze toe aan het onCollisionEnter-attribuut van de betreffende RigidBody.

07

EVENTS

export default function Experience()
{
    const collisionEnter = () =>
    {
        console.log('collision!')
    }
    
<RigidBody
    ref={ cube }
    position={ [ 1.5, 2, 0 ] }
    gravityScale={ 1 }
    restitution={ 0 }
    friction={ 0.7 }
    colliders={ false }
    onCollisionEnter={ collisionEnter }
>

ENTER

Om onze sound af te spelen, moeten we deze natuurlijk eerst aanmaken.

07

EVENTS

import { useState, useRef } from 'react'

export default function Experience()
{
    const [ hitSound ] = useState(() => new Audio('./oof.mp3'))

    // ...
}

Gebruik nu deze audio file in onze collisionEnter function.

const collisionEnter = () =>
{
    hitSound.currentTime = 0.5
    hitSound.volume = Math.random()
    hitSound.play()
}

Ga terug naar je scene en luister. Hoor je niets? Klik dan eerst eens op je scene.

EXIT

Implementeer een console.log in de onCollisionExit-handler om de gebeurtenis te registreren.

07

EVENTS

<RigidBody
    ref={ cube }
    position={ [ 1.5, 2, 0 ] }
    gravityScale={ 1 }
    restitution={ 0 }
    friction={ 0.7 }
    colliders={ false }
    onCollisionEnter={ collisionEnter }
    onCollisionExit={ () => { console.log('exit') } }
>
    {/* ... */}
</RigidBody>

onCollisionExit wordt getriggerd wanneer een object geen contact meer heeft met het betreffende object.

ONSLEEP/WAKE

Geef nu een console mee op de sleep en wake function en zie wat er gebeurd in de console.

07

EVENTS

<RigidBody
    ref={ cube }
    position={ [ 1.5, 2, 0 ] }
    gravityScale={ 1 }
    restitution={ 0 }
    friction={ 0.7 }
    colliders={ false }
    onCollisionEnter={ collisionEnter }
    onCollisionExit={ () => { console.log('exit') } }
    onSleep={ () => { console.log('sleep') } }
    onWake={ () => { console.log('wake') } }
>
		{/* ... */}
</RigidBody>

Objecten die voor een bepaalde periode in rust zijn, worden in een sleep-modus geplaatst. Ze blijven in deze toestand totdat een kracht wordt uitgeoefend, waarna ze de sleep-modus verlaten (wake).

CONCLUSION

ENTER

07

EVENTS

EXIT

SLEEP/WAKE

TECH3/7 - Let's Get Physical

By Niels Minne

TECH3/7 - Let's Get Physical

  • 112