UNPKG

@playcanvas/react

Version:

A React renderer for PlayCanvas – build interactive 3D applications using React's declarative paradigm.

62 lines 3.48 kB
"use client"; import { useEffect } from "react"; import { useComponent, useParent } from "../hooks/index.js"; import { usePhysics } from "../contexts/physics-context.js"; import { validatePropsPartial, warnOnce, createComponentDefinition, getStaticNullApplication } from "../utils/validation.js"; import { Entity } from "playcanvas"; /** * The Collision component adds a collider to the entity. This enables the entity to collide with other entities. * You can manually define the shape of the collider with the `type` prop, or let the component infer the shape from a `Render` component. * @param {CollisionProps} props - The props to pass to the collision component. * @see https://api.playcanvas.com/engine/classes/CollisionComponent.html * * @example * <Entity> * <Collision type="box" /> * <Render /> // will infer the shape from the render component * </Entity> */ export const Collision = (props) => { const entity = useParent(); const { isPhysicsEnabled, isPhysicsLoaded, physicsError } = usePhysics(); const safeProps = validatePropsPartial(props, componentDefinition); useEffect(() => { if (!isPhysicsEnabled) { warnOnce('The `<Collision>` component requires physics to be enabled.\n\n' + 'To fix this:\n' + '1. Add `usePhysics` prop to your root Application component:\n' + ' <Application usePhysics>\n' + ' <Entity>\n' + ' <Collision type="box" />\n' + ' </Entity>\n' + ' </Application>\n\n' + '2. Make sure you have the required dependencies installed:\n' + ' npm install sync-ammo\n\n' + 'For more information, see: https://playcanvas-react.vercel.app/docs/physics'); } if (physicsError) { warnOnce(`Physics initialization failed: ${physicsError.message}\n\n` + 'To fix this:\n' + '1. Install the required dependency:\n' + ' npm install sync-ammo\n\n' + '2. Make sure your bundler is configured to handle WASM files\n\n' + '3. Check that your server is configured to serve .wasm files with the correct MIME type\n\n' + 'For more information, see: https://playcanvas-react.vercel.app/docs/physics#troubleshooting'); } }, [isPhysicsEnabled, physicsError]); // If no type is defined, infer if possible from a render component const type = entity.render && props.type === undefined ? entity.render.type : props.type; // Always call useComponent - it will handle component lifecycle internally useComponent(isPhysicsLoaded ? "collision" : null, { ...safeProps, type }, componentDefinition.schema); return null; }; const componentDefinition = createComponentDefinition("Collision", () => new Entity("mock-collision", getStaticNullApplication()).addComponent('collision'), (component) => component.system.destroy(), "CollisionComponent"); componentDefinition.schema = { ...componentDefinition.schema, type: { validate: (value) => typeof value === 'string' && ['box', 'capsule', 'compound', 'cone', 'cylinder', 'mesh', 'sphere'].includes(value), errorMsg: (value) => `Invalid value for prop "type": ${value}. Expected one of: "box", "capsule", "compound", "cone", "cylinder", "mesh", "sphere".`, default: "box" } }; //# sourceMappingURL=Collision.js.map