Search code examples
reactjsthree.jsreact-three-fiberrapier-3d

React three rapier scene limitation for objects


There is a 3d scene on which objects are flying and I need to prevent them from flying far off the screen, are there any good practices for this?

I was trying to make walls out of boxGeometry to keep objects from flying out and stretch them across the viewport

Are there any other good practices for dealing with this problem?


Solution

  • You could try and use CuboidColliders. 6X of these and you would have containment.

    import { CuboidCollider } from "@react-three/rapier";
    
    export function Wall({
      height,
      width,
      depth,
      x,
      y,
      z,
    }: {
      height: number;
      width: number;
      depth: number;
      x: number;
      y: number;
      z: number;
    }) {
      return <CuboidCollider args={[width, height, depth]} position={[x, y, z]} />;
    }
    
    import { RigidBody } from "@react-three/rapier";
    import { useThree } from "@react-three/fiber";
    import { Wall } from "./Wall";
    
    export function Box() {
      const { viewport } = useThree(); //viewport bounds
      const wallHeight = 25; // depth
      return (
        <RigidBody type="fixed">
          {/* FRONT */}
          <Wall
            width={viewport.width / 2}
            height={wallHeight / 2}
            depth={1}
            x={0}
            y={wallHeight / 2}
            z={viewport.height / 2}
          />
          {/* BACK */}
          <Wall
            width={viewport.width / 2}
            height={wallHeight / 2}
            depth={1}
            x={0}
            y={wallHeight / 2}
            z={-viewport.height / 2}
          />
          {/* RIGHT */}
          <Wall
            width={1}
            height={wallHeight / 2}
            depth={viewport.height / 2}
            x={viewport.width / 2}
            y={wallHeight / 2}
            z={0}
          />
          {/* LEFT */}
          <Wall
            width={1}
            height={wallHeight / 2}
            depth={viewport.height / 2}
            x={-viewport.width / 2}
            y={wallHeight / 2}
            z={0}
          />
          {/* BOTTOM */}
          <Wall
            width={viewport.width / 2}
            height={0.5}
            depth={viewport.height / 2}
            x={0}
            y={-1}
            z={0}
          />
          {/* TOP */}
          <Wall
            width={viewport.width / 2}
            height={0.5}
            depth={viewport.height / 2}
            x={0}
            y={wallHeight}
            z={0}
          />
        </RigidBody>
      );
    }