Skip to main content

Entity Management

import React, {
FC,
useRef,
useState,
} from 'react'
import { useControls } from 'leva';
import _ from 'lodash';
import { Vector3 } from 'three';
import {
Box,
OrbitControls,
PerspectiveCamera,
} from '@react-three/drei';
import { Canvas } from '@react-three/fiber';
import {
Entity,
Facet,
rad,
useAnimationFrame,
useECS,
useQuery,
useSystem,
} from '@react-ecs/core';
import { ThreeView } from '@react-ecs/three';
class Spinning extends Facet<Spinning> {
rotation = new Vector3(0, 0, 0);
}
const SpinningSystem = () => {
const query = useQuery(e => e.hasAll(ThreeView, Spinning));
return useSystem((dt: number) => {
query.loop([ThreeView, Spinning], (e, [view, spin]) => {
const transform = view.ref.current!;
const rotation = spin.rotation.clone().multiplyScalar(dt);
const newRotation = transform.rotation
.toVector3()
.add(rotation);
transform.rotation.setFromVector3(newRotation);
});
});
};
const SpinCube = ({ amount }) => {
return (
<Entity>
<Spinning rotation={new Vector3(amount.x, amount.y, amount.z)} />
<ThreeView>
<Box position={[Math.random() * 3, Math.random() * 3, 0]} scale={3} rotation={[rad(45), rad(45), 0]}>
<meshLambertMaterial />
</Box>
</ThreeView>
</Entity>
);
};
const Generator = (props) => {
const tick = useRef(0)
const [gen, setGen] = useState(0);
useSystem(dt => {
tick.current += dt;
if (tick.current > 1) {
tick.current = 0
setGen(gen + 1)
}
})
return <>{_.times(5, _ => <SpinCube key={Math.random()} amount={{ x: 1, y: 1, z: 1}} />)}</>
}
export const EntityManagementScene: FC = () => {
const ECS = useECS();
useAnimationFrame(ECS.update);
const { amount } = useControls('spin', {amount: {value: { x: 1, y: 1, z: 1}}})
const del = () => ECS.engine.removeEntity(ECS.engine.entities[0])
return (
<>
<button onClick={del}>Delete</button>
<Canvas>
<OrbitControls />
<PerspectiveCamera makeDefault position={[0, 0, 8]}>
<ambientLight intensity={.2} />
<directionalLight position={[1, 1, 1]} />
</PerspectiveCamera>
<ECS.Provider>
<SpinningSystem />
<Generator />
</ECS.Provider>
</Canvas>
</>
);
};