@playcanvas/react
Version:
A React renderer for PlayCanvas – build interactive 3D applications using React's declarative paradigm.
62 lines • 3.47 kB
JavaScript
"use client";
import { useEffect } from "react";
import { useComponent, useParent } from "../hooks";
import { usePhysics } from "../contexts/physics-context";
import { validatePropsPartial, warnOnce, createComponentDefinition, getStaticNullApplication } from "../utils/validation";
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