UNPKG

@jaimebboyjt/tres-fps-controls

Version:

Easy to use First Person Controls for TresJS

257 lines (197 loc) 8.21 kB
# Tres FPS controls > First person shooter controls to easily create 3D shooter experiences (or other first person experiences). - 💡 Works out of the box - ⚡️ Powered by [Tresjs](https://tresjs.org/), [VueJs](https://vuejs.org/) + [ThreeJs](https://threejs.org/) - 🦾 Fully configurable ## Installation ```bash pnpm i @jaimebboyjt/tres-fps-controls ``` ## Demos ![Alt text](/public/Fake_Doom_demo.gif) All the examples can be found in: [Examples](https://github.com/JaimeTorrealba/fps-controls/tree/main/playground/src/pages). # How to use it To get started you can simply import the main component and use it. ```html <script setup> import { TresCanvas } from "@tresjs/core"; import { fpsControls } from "@jaimebboyjt/tres-fps-controls"; </script> <template> <TresCanvas window-size> <TresPerspectiveCamera :position="[0, 0, 3]" :fov="45" :aspect="1" :near="0.1" :far="1000" /> <fpsControls /> </TresCanvas> </template> ``` That's it. Now you're going to have a shooter controller. The WASD keys allow you to move and the mouse pointer changes where you look. > [!NOTE] > This package uses [PointerLockControls](https://cientos.tresjs.org/guide/controls/pointer-lock-controls.html) from [cientos](https://cientos.tresjs.org/). ## ControlsKey We can provide a `controlsKeys` prop to change, add or remove some of the basic functionalities. ```js export default { props: { controlsKeys: { type: Array, default: () => [ { name: 'forward', key: 'w' }, { name: 'backward', key: 's' }, { name: 'left', key: 'a' }, { name: 'right', key: 'd' }, // Optionals { name: 'run', key: 'Shift', speed: moveSpeed * 2 }, { name: 'creep', key: 'ctrl', speed: moveSpeed * 0.25 }, // Mouse actions { name: 'leftClick', action: () => { } }, { name: 'rightClick', action: () => { } }, { name: 'middleClick', action: () => { } }, { name: 'wheelActionUp', action: () => { } }, { name: 'wheelActionDown', action: () => { } }, // Key actions { name: 'actions', actions: // You can have as many events as you want 🥳 [ { name: 'action', key: 'e', action: () => {} }, { name: 'action', key: 'q', action: () => {} }, { name: 'action', key: 'r', action: () => {} }, { name: 'action', key: 'f', action: () => {} }, ], }, ], }, } } ``` > [!TIP] > Under the hood we use [useMagicKeys](https://vueuse.org/core/useMagicKeys/#usemagickeys). Check out [all the possible keycodes](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values). As you can see we can provide different actions, including an array of actions using the keyboard. ```html <script setup> import { TresCanvas } from "@tresjs/core"; import { fpsControls } from "@jaimebboyjt/tres-fps-controls"; const keyboardMap = [ { name: "run", key: "q", speed: 0.5 }, { name: "creep", key: "e" }, { name: "leftClick", action: () => animationSword() }, { name: "actions", actions: [ { name: "action2", key: "f", action: () => console.log("F press") }, { name: "action4", key: "r", action: () => console.log("R press") }, ], }, { name: "wheelActionUp", action: () => console.log("up") }, { name: "wheelActionDown", action: () => console.log("down") }, ]; </script> <template> <TresCanvas window-size> <TresPerspectiveCamera :position="[0, 0, 3]" :fov="45" :aspect="1" :near="0.1" :far="1000" /> <fpsControls :controlsKeys="keyboardMap" /> </TresCanvas> </template> ``` ### Other props | Prop | Description | Type | Default | | :-------------- | :---------------------------------------------------------------------------------------- | ----------------- | ----------- | | **moveSpeed** | Move speed | Number | `0.1` | | **camera** | The camera to control | Camera | `undefined` | | **domElement** | The dom element to listen to | HTMLCanvasElement | `undefined` | | **selector** | Accept an id element as string, if it is set, the new element will be used as the trigger | String | `undefined` | ## Add weapons (models) Do you want to add a weapon? Like a pistol, that is always with your character? It couldn't be easier: Just add your desired model as a slot (learn how to load models here). For example: ```html ... <fpsControls> <Suspense> <GLTFModel path="/PixelArt Medieval Sword.glb" :scale="0.4" :position="[-4.5, -3, -5]" // Don't forget set the z axis :rotation="[0, 1, 0]" /> </Suspense> </fpsControls> ... ``` This will make your model update its position each time you move. > [!IMPORTANT] > Normally you would set up the z axis, so the model is in front of you camera. ### Expose methods Do you still need more configurations? We provide all the methods for you, **exposed** by the component, so you can use them as you like. ```js const exposeMethods = { root: PointerLockControlsRef, models: wrapperRef, moveMethods: { forward: () => walkSystem.moveForward(), backward: () => walkSystem.moveBackward(), left: () => walkSystem.moveLeft(), right: () => walkSystem.moveRight(), run: () => walkSystem.applyRun(), creep: () => walkSystem.applyCreep(), stopCreep: () => walkSystem.stopCreep(), stopRun: () => walkSystem.stopRun(), stopSideward: () => walkSystem.stopSideward(), stopForward: () => walkSystem.stopForward(), } } ``` For granular control each method comes with its `stop` method. You can access all these methods using [Template ref](https://vuejs.org/guide/essentials/template-refs.html#template-refs), as you normally would do with your TresJs components. ### Events We also provide some reactive events. Ej: ```html <script> import { fpsControls } from 'fpsControls' const handleState = (e) => console.log(e) const handleLock = (e) => console.log(e) const onChange = (e) => console.log(e) </script> <template> <TresCanvas window-size> <TresPerspectiveCamera :position="[0, 0, 3]" :fov="45" :aspect="1" :near="0.1" :far="1000" /> <fpsControls @state="handleState" @isLock="handleLock" @change="onChange" /> </TresCanvas> </template> ``` | Event | Description | | :--------- | :---------------------------------------------------------- | | **state** | trigger when the state changes. | | **isLock** | trigger whether the pointer is locked. | | **change** | trigger when the character makes a move (moves the camera). | Posible states: ```js const states = { idle: 'idle', walking: 'walking', running: 'running', creeping: 'creeping', } ``` ## Gamepad [Check example](/playground/src/pages/basics/GamepadDemo.vue) inside playground on how to use the a gamepad with this repo :D | ## Contributing I appreciate your interest in this project! If you have any feedback, suggestions, or resources related to the controller, please feel free to share. ## License [MIT](/LICENSE) ## Sponsors If you like this package you can support my work [here](https://github.com/sponsors/JaimeTorrealba ☺️. A github star or just some words of appreciation are incredible.