muse.place · discord · we are hiring!
Visit the codesandbox to instantly play with the package
https://codesandbox.io/s/e9w29
Clone the starter repo to give yourself a solid starting point
https://github.com/spacesvr/spacesvr-starter
You could set up the framework in your sleep. Just import the package
npm install spacesvr
# or
yarn add spacesvr
and copy/paste 9 lines of code
import { StandardEnvironment, Logo } from "spacesvr";
const App = () => {
return (
<StandardEnvironment>
<Logo floating rotating />
</StandardEnvironment>
);
};
The main functionality comes from the Environment
components which provide variations of...
- a player with a control scheme
- physics
- default components
- loading menu
- pause menu
Under the hood it enables cannon physics and react-three-fiber code with a canvas. All you have to do is wrap your react-three-fiber code in an environment and you will be able to navigate your space on mobile and desktop!
The useEnvironment
hook is your direct access to the environment state. It can be used anywhere
inside an Environment
component and gives you an EnvironmentState
, defined as:
{
paused: boolean; // whether the pointer lock controls are engaged
setPaused: (p: boolean, overlay?: string) => void; // set the paused state, along with overlay
overlay: string | null; // null if no overlay enabled or string with id of currenly open overlay
device: { xr: boolean; mobile: boolean; desktop: boolean; } // flags for user's current device state
containerRef: MutableRefObject<HTMLDivElement | null>; // ref to html container (parent of Canvas)
}
The usePlayer
hook is your direct access to the player state. It can be used anywhere
inside an Environment
component and gives you an PlayerState
, defined as:
{
position: PlayerVec; // extends .set(v: Vector3) and .get() abilities to player's position
velocity: PlayerVec; // extends .set(v: Vector3) and .get() abilities to player's velocity
controls: PlayerControls; // allows you to .lock(), .unlock(), and check whether it .isLocked()
raycaster: THREE.Raycaster; // reference to player's raycaster updated to appropriate device type (not xr yet)
}
Your worlds can now run in a simulation! To enable it you can run a
server out of examples/server/app.js
and pass the corresponding parameters as simulationProps
to the
StandardEnvironment
component. This is a work in progress!
{
signalHost?: string;
signalPort?: number;
signalPath?: string;
socketServer?: string;
frequency?: number; // number of times per second to update
}
Modifiers, add functionality to any 3d component in different ways. For example, the Floating
modifier will make its children steadily float up and down. Perfect for quickly adding
animations to components!
<Floating height={2} speed={2}>
<mesh>
<sphereBufferGeometry args={[1]} />
<meshStandardMaterial color="white" />
</mesh>
</Floating>
The Standard Environment defines the following:
- 2 unit tall player with WASD movement and pointer lock controls on desktop, joystick and drag controls on mobile
- Physics enabled, ground plane at y=0
- Custom loading menu
- Custom pause menu
<StandardEnvironment
canvasProps={{...}} // props to be passed along to the r3f canvas
physicsProps={{...}} // props to be passed along to cannon.js
playerProps={{
pos: [INIT_X, INIT_Y, INIT_Z], // initial position
rot: 0, // initial rotation,
speed: 3.2 // meters per second (~1.4 walking, ~2.2 jogging)
}}
disableGround={false} // disable ground physics plane
simulationProps={{...}} // props to be passed to simulation
/>
An arrow icon
<Arrow dark={true} />
A positional audio component that will play the passed in audio url. Handles media playback rules for Safari, iOS, etc.
<Audio
url="https://link-to-your-audio.mp3"
position={[0, 4, 0]}
volume={1}
rollOff={1}
dCone={new Vector3(coneInnerAngle, coneOuterAngle, coneOuterGain)} // defaults should be fine
/>
Easily set the background color of your space
<Background color="blue" />
Add fog to your scene. Required rather than attaching to parent since direct parent is <Physics />
<Fog color="blue" near={10} far={100} />
Set the scene background to an hdr file. You can find free hdr files here: https://hdrihaven.com/
<HDRI
src="https://link-to-your-hdri.hdr"
hideBackground={false} // set to true to only apply radiance
/>
Quickly add an image to your scene
<Image
src="https://link-to-your-image.png"
size={1} // size, default normalized to longest side = 1
framed // adds a frame
transparent // enables transparency on the image
material={THREE.Material} // custom material for the frame
/>
Adds a cool Spaces Logo
<Logo
floating // makes logo slowly float
rotating // makes logo slowly rotate
/>
A 3D text component with a default font of Myriad Pro. Custom fonts need to be converted to a json file, which can be done here: https://gero3.github.io/facetype.js/. Note: this is expensive, so if you want a lot of text look at Drei's Text component, extended from Troika-3d-Text.
<Text
text="Hello Space"
vAlign="center" // vertical align relative to the y component
hAlign="center" // horizontal align relative to the x component
size={1} // scale
color="#000000" // color
font={"https://your-font-file.json"} // default is Myriad Pro
material={THREE.Material} // custom material to pass in
/>
Add a video file to your space with positional audio. Handles media playback rules for Safari, iOS, etc.
<Video
src="https://link-to-your-video.mp4"
size={1} // size, default normalized to longest side = 1
volume={1}
muted // mutes the video
framed // adds a frame
material={THREE.Material} // custom material for the frame
/>
Makes its children face the player
<FacePlayer
lockX={false} // lock rotation on the x axis
lockY={false} // just eyeball it
lockZ={false}
>
<Stuff />
</FacePlayer>
Makes its children float up and down
<Floating
height={1} // the height it should float
speed={1} // just eyeball it
>
<Stuff />
</Floating>
Makes its children react to onclick and on hover methods
<Interactable
onClick={() => console.log("Ive been clicked!")}
onHovered={() => console.log("Ive been hovered!")}
onUnHovered={() => console.log("Ive been unhovered?")}
>
<Stuff />
</Interactable>
Makes its children spin
<Spinning
xSpeed={0} // speed to spin around axis
ySpeed={1} // y axis is 1 by default
zSpeed={0} // 0 = no spin on axis
>
<Stuff />
</Spinning>
Puts its children in the player's field of view at all times. Think of it as a toolbelt.
<Tool
pos={[0, 0]} // position on screen from [-1, -1] to [1, 1]
face={true} // whether the tool should face the screen
distance={1} // how far away to place the item. It will scale as it moves away
pinY={false} // pin the tool on the y axis
>
<Stuff />
</Tool>
These examples were made as we were building the framework so the code is outdated