@directivegames/genesys.sdk 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/README.md +60 -0
  2. package/dist/src/asset-pack/eslint.config.js +43 -0
  3. package/dist/src/asset-pack/scripts/postinstall.js +64 -0
  4. package/dist/src/asset-pack/src/index.js +1 -0
  5. package/dist/src/core/cli.js +306 -0
  6. package/dist/src/core/common.js +324 -0
  7. package/dist/src/core/index.js +6 -0
  8. package/dist/src/core/tools/build-project.js +450 -0
  9. package/dist/src/core/tools/index.js +2 -0
  10. package/dist/src/core/tools/new-asset-pack.js +150 -0
  11. package/dist/src/core/tools/new-project.js +292 -0
  12. package/dist/src/core/types.js +1 -0
  13. package/dist/src/dependencies.js +82 -0
  14. package/dist/src/electron/IpcSerializableError.js +38 -0
  15. package/dist/src/electron/api.js +7 -0
  16. package/dist/src/electron/backend/actions.js +56 -0
  17. package/dist/src/electron/backend/handler.js +441 -0
  18. package/dist/src/electron/backend/logging.js +41 -0
  19. package/dist/src/electron/backend/main.js +315 -0
  20. package/dist/src/electron/backend/menu.js +208 -0
  21. package/dist/src/electron/backend/state.js +201 -0
  22. package/dist/src/electron/backend/tools/const.js +9 -0
  23. package/dist/src/electron/backend/tools/file-server.js +383 -0
  24. package/dist/src/electron/backend/tools/open-project.js +261 -0
  25. package/dist/src/electron/backend/window.js +161 -0
  26. package/dist/src/templates/eslint.config.js +43 -0
  27. package/dist/src/templates/scripts/genesys/build-project.js +42 -0
  28. package/dist/src/templates/scripts/genesys/calc-bounding-box.js +205 -0
  29. package/dist/src/templates/scripts/genesys/common.js +36 -0
  30. package/dist/src/templates/scripts/genesys/const.js +9 -0
  31. package/dist/src/templates/scripts/genesys/dev/dump-default-scene.js +8 -0
  32. package/dist/src/templates/scripts/genesys/dev/generate-manifest.js +116 -0
  33. package/dist/src/templates/scripts/genesys/dev/launcher.js +39 -0
  34. package/dist/src/templates/scripts/genesys/dev/storage-provider.js +188 -0
  35. package/dist/src/templates/scripts/genesys/dev/update-template-scenes.js +67 -0
  36. package/dist/src/templates/scripts/genesys/doc-server.js +12 -0
  37. package/dist/src/templates/scripts/genesys/genesys-mcp.js +413 -0
  38. package/dist/src/templates/scripts/genesys/mcp/doc-tools.js +70 -0
  39. package/dist/src/templates/scripts/genesys/mcp/editor-functions.js +123 -0
  40. package/dist/src/templates/scripts/genesys/mcp/editor-tools.js +51 -0
  41. package/dist/src/templates/scripts/genesys/mcp/get-scene-state.js +26 -0
  42. package/dist/src/templates/scripts/genesys/mcp/run-subprocess.js +23 -0
  43. package/dist/src/templates/scripts/genesys/mcp/search-actors.js +703 -0
  44. package/dist/src/templates/scripts/genesys/mcp/search-assets.js +296 -0
  45. package/dist/src/templates/scripts/genesys/mcp/utils.js +234 -0
  46. package/dist/src/templates/scripts/genesys/misc.js +32 -0
  47. package/dist/src/templates/scripts/genesys/mock.js +5 -0
  48. package/dist/src/templates/scripts/genesys/place-actors.js +112 -0
  49. package/dist/src/templates/scripts/genesys/post-install.js +25 -0
  50. package/dist/src/templates/scripts/genesys/remove-engine-comments.js +113 -0
  51. package/dist/src/templates/scripts/genesys/storageProvider.js +146 -0
  52. package/dist/src/templates/scripts/genesys/validate-prefabs.js +115 -0
  53. package/dist/src/templates/src/index.js +20 -0
  54. package/dist/src/templates/src/templates/firstPerson/src/auto-imports.js +1 -0
  55. package/dist/src/templates/src/templates/firstPerson/src/game.js +30 -0
  56. package/dist/src/templates/src/templates/firstPerson/src/player.js +60 -0
  57. package/dist/src/templates/src/templates/fps/src/auto-imports.js +1 -0
  58. package/dist/src/templates/src/templates/fps/src/game.js +30 -0
  59. package/dist/src/templates/src/templates/fps/src/player.js +64 -0
  60. package/dist/src/templates/src/templates/fps/src/weapon.js +62 -0
  61. package/dist/src/templates/src/templates/freeCamera/src/auto-imports.js +1 -0
  62. package/dist/src/templates/src/templates/freeCamera/src/game.js +30 -0
  63. package/dist/src/templates/src/templates/freeCamera/src/player.js +43 -0
  64. package/dist/src/templates/src/templates/sideScroller/src/auto-imports.js +1 -0
  65. package/dist/src/templates/src/templates/sideScroller/src/const.js +43 -0
  66. package/dist/src/templates/src/templates/sideScroller/src/game.js +103 -0
  67. package/dist/src/templates/src/templates/sideScroller/src/level-generator.js +249 -0
  68. package/dist/src/templates/src/templates/sideScroller/src/player.js +105 -0
  69. package/dist/src/templates/src/templates/thirdPerson/src/auto-imports.js +1 -0
  70. package/dist/src/templates/src/templates/thirdPerson/src/game.js +30 -0
  71. package/dist/src/templates/src/templates/thirdPerson/src/player.js +63 -0
  72. package/dist/src/templates/src/templates/vehicle/src/auto-imports.js +1 -0
  73. package/dist/src/templates/src/templates/vehicle/src/base-vehicle.js +122 -0
  74. package/dist/src/templates/src/templates/vehicle/src/game.js +33 -0
  75. package/dist/src/templates/src/templates/vehicle/src/mesh-vehicle.js +189 -0
  76. package/dist/src/templates/src/templates/vehicle/src/player.js +102 -0
  77. package/dist/src/templates/src/templates/vehicle/src/primitive-vehicle.js +259 -0
  78. package/dist/src/templates/src/templates/vehicle/src/ui-hints.js +100 -0
  79. package/dist/src/templates/src/templates/vr-game/src/auto-imports.js +1 -0
  80. package/dist/src/templates/src/templates/vr-game/src/game.js +55 -0
  81. package/dist/src/templates/src/templates/vr-game/src/sample-vr-actor.js +29 -0
  82. package/dist/src/templates/vite.config.js +46 -0
  83. package/package.json +176 -0
  84. package/scripts/post-install.ts +143 -0
  85. package/src/asset-pack/.gitattributes +89 -0
  86. package/src/asset-pack/eslint.config.js +45 -0
  87. package/src/asset-pack/gitignore +11 -0
  88. package/src/asset-pack/scripts/postinstall.ts +81 -0
  89. package/src/asset-pack/src/index.ts +0 -0
  90. package/src/asset-pack/tsconfig.json +34 -0
  91. package/src/templates/.cursor/mcp.json +20 -0
  92. package/src/templates/.cursorignore +2 -0
  93. package/src/templates/.gitattributes +89 -0
  94. package/src/templates/.vscode/settings.json +6 -0
  95. package/src/templates/AGENTS.md +86 -0
  96. package/src/templates/CLAUDE.md +1 -0
  97. package/src/templates/README.md +24 -0
  98. package/src/templates/eslint.config.js +45 -0
  99. package/src/templates/gitignore +11 -0
  100. package/src/templates/index.html +34 -0
  101. package/src/templates/pnpm-lock.yaml +3676 -0
  102. package/src/templates/scripts/genesys/build-project.ts +51 -0
  103. package/src/templates/scripts/genesys/calc-bounding-box.ts +272 -0
  104. package/src/templates/scripts/genesys/common.ts +46 -0
  105. package/src/templates/scripts/genesys/const.ts +9 -0
  106. package/src/templates/scripts/genesys/dev/dump-default-scene.ts +11 -0
  107. package/src/templates/scripts/genesys/dev/generate-manifest.ts +146 -0
  108. package/src/templates/scripts/genesys/dev/launcher.ts +46 -0
  109. package/src/templates/scripts/genesys/dev/storage-provider.ts +229 -0
  110. package/src/templates/scripts/genesys/dev/update-template-scenes.ts +84 -0
  111. package/src/templates/scripts/genesys/doc-server.ts +16 -0
  112. package/src/templates/scripts/genesys/genesys-mcp.ts +526 -0
  113. package/src/templates/scripts/genesys/mcp/doc-tools.ts +86 -0
  114. package/src/templates/scripts/genesys/mcp/editor-functions.ts +151 -0
  115. package/src/templates/scripts/genesys/mcp/editor-tools.ts +73 -0
  116. package/src/templates/scripts/genesys/mcp/get-scene-state.ts +35 -0
  117. package/src/templates/scripts/genesys/mcp/run-subprocess.ts +30 -0
  118. package/src/templates/scripts/genesys/mcp/search-actors.ts +858 -0
  119. package/src/templates/scripts/genesys/mcp/search-assets.ts +380 -0
  120. package/src/templates/scripts/genesys/mcp/utils.ts +281 -0
  121. package/src/templates/scripts/genesys/misc.ts +42 -0
  122. package/src/templates/scripts/genesys/mock.ts +6 -0
  123. package/src/templates/scripts/genesys/place-actors.ts +179 -0
  124. package/src/templates/scripts/genesys/post-install.ts +30 -0
  125. package/src/templates/scripts/genesys/prefab.schema.json +85 -0
  126. package/src/templates/scripts/genesys/remove-engine-comments.ts +135 -0
  127. package/src/templates/scripts/genesys/run-mcp-inspector.bat +5 -0
  128. package/src/templates/scripts/genesys/storageProvider.ts +182 -0
  129. package/src/templates/scripts/genesys/validate-prefabs.ts +138 -0
  130. package/src/templates/src/index.ts +22 -0
  131. package/src/templates/src/templates/firstPerson/assets/default.genesys-scene +166 -0
  132. package/src/templates/src/templates/firstPerson/src/auto-imports.ts +0 -0
  133. package/src/templates/src/templates/firstPerson/src/game.ts +39 -0
  134. package/src/templates/src/templates/firstPerson/src/player.ts +63 -0
  135. package/src/templates/src/templates/fps/assets/default.genesys-scene +9460 -0
  136. package/src/templates/src/templates/fps/assets/models/SM_Beam_400.glb +0 -0
  137. package/src/templates/src/templates/fps/assets/models/SM_ChamferCube.glb +0 -0
  138. package/src/templates/src/templates/fps/assets/models/SM_Floor_Thick_400x400.glb +0 -0
  139. package/src/templates/src/templates/fps/assets/models/SM_Floor_Thick_400x400_Orange.glb +0 -0
  140. package/src/templates/src/templates/fps/assets/models/SM_Floor_Thin_400x400.glb +0 -0
  141. package/src/templates/src/templates/fps/assets/models/SM_Floor_Thin_400x400_Orange.glb +0 -0
  142. package/src/templates/src/templates/fps/assets/models/SM_Ramp_400x400.glb +0 -0
  143. package/src/templates/src/templates/fps/assets/models/SM_Rifle.glb +0 -0
  144. package/src/templates/src/templates/fps/assets/models/SM_Wall_Thin_400x200.glb +0 -0
  145. package/src/templates/src/templates/fps/assets/models/SM_Wall_Thin_400x200_Orange.glb +0 -0
  146. package/src/templates/src/templates/fps/assets/models/SM_Wall_Thin_400x400.glb +0 -0
  147. package/src/templates/src/templates/fps/assets/models/SM_Wall_Thin_400x400_Orange.glb +0 -0
  148. package/src/templates/src/templates/fps/src/auto-imports.ts +0 -0
  149. package/src/templates/src/templates/fps/src/game.ts +39 -0
  150. package/src/templates/src/templates/fps/src/player.ts +69 -0
  151. package/src/templates/src/templates/fps/src/weapon.ts +54 -0
  152. package/src/templates/src/templates/freeCamera/assets/default.genesys-scene +166 -0
  153. package/src/templates/src/templates/freeCamera/src/auto-imports.ts +0 -0
  154. package/src/templates/src/templates/freeCamera/src/game.ts +39 -0
  155. package/src/templates/src/templates/freeCamera/src/player.ts +45 -0
  156. package/src/templates/src/templates/sideScroller/assets/default.genesys-scene +122 -0
  157. package/src/templates/src/templates/sideScroller/src/auto-imports.ts +0 -0
  158. package/src/templates/src/templates/sideScroller/src/const.ts +46 -0
  159. package/src/templates/src/templates/sideScroller/src/game.ts +122 -0
  160. package/src/templates/src/templates/sideScroller/src/level-generator.ts +361 -0
  161. package/src/templates/src/templates/sideScroller/src/player.ts +125 -0
  162. package/src/templates/src/templates/thirdPerson/assets/default.genesys-scene +166 -0
  163. package/src/templates/src/templates/thirdPerson/src/auto-imports.ts +0 -0
  164. package/src/templates/src/templates/thirdPerson/src/game.ts +39 -0
  165. package/src/templates/src/templates/thirdPerson/src/player.ts +61 -0
  166. package/src/templates/src/templates/vehicle/assets/default.genesys-scene +226 -0
  167. package/src/templates/src/templates/vehicle/assets/models/cyberTruck/chassis.glb +0 -0
  168. package/src/templates/src/templates/vehicle/assets/models/cyberTruck/wheel.glb +0 -0
  169. package/src/templates/src/templates/vehicle/src/auto-imports.ts +0 -0
  170. package/src/templates/src/templates/vehicle/src/base-vehicle.ts +145 -0
  171. package/src/templates/src/templates/vehicle/src/game.ts +43 -0
  172. package/src/templates/src/templates/vehicle/src/mesh-vehicle.ts +191 -0
  173. package/src/templates/src/templates/vehicle/src/player.ts +109 -0
  174. package/src/templates/src/templates/vehicle/src/primitive-vehicle.ts +266 -0
  175. package/src/templates/src/templates/vehicle/src/ui-hints.ts +101 -0
  176. package/src/templates/src/templates/vr-game/assets/default.genesys-scene +247 -0
  177. package/src/templates/src/templates/vr-game/src/auto-imports.ts +1 -0
  178. package/src/templates/src/templates/vr-game/src/game.ts +66 -0
  179. package/src/templates/src/templates/vr-game/src/sample-vr-actor.ts +26 -0
  180. package/src/templates/tsconfig.json +35 -0
  181. package/src/templates/vite.config.ts +52 -0
@@ -0,0 +1,122 @@
1
+ import * as ENGINE from 'genesys.js';
2
+ import * as THREE from 'three';
3
+ import { VehiclePlayer } from './player.js';
4
+ /**
5
+ * Base vehicle class that provides common vehicle functionality
6
+ *
7
+ * Key points:
8
+ * - Handles camera setup with follow component for smooth third-person view
9
+ * - Manages player interaction (enter/exit vehicle with proximity detection)
10
+ * - Provides E key input handler for vehicle exit
11
+ * - Calculates safe exit position when player leaves vehicle
12
+ * - Automatically switches possession between player and vehicle
13
+ *
14
+ */
15
+ export class BaseVehicle extends ENGINE.Pawn {
16
+ interactionDistance = 5;
17
+ nearbyPlayer = null;
18
+ enteredPlayer = null;
19
+ doBeginPlay() {
20
+ super.doBeginPlay();
21
+ this.setupCamera();
22
+ this.setupVicinityCheck();
23
+ this.setupExitHandler();
24
+ }
25
+ setupCamera() {
26
+ // create a follow component for smooth camera movement
27
+ const followComponent = new ENGINE.FollowComponent({
28
+ positionOffset: new THREE.Vector3(0, 4, 10),
29
+ positionDamping: 0.02,
30
+ lookAtOffset: new THREE.Vector3(0, 0, 0),
31
+ target: this.rootComponent,
32
+ useCameraLookAtConvention: true,
33
+ });
34
+ this.rootComponent.add(followComponent);
35
+ // create a camera and add it to the follow component
36
+ const camera = new THREE.PerspectiveCamera(ENGINE.CAMERA_FOV, 1, ENGINE.CAMERA_NEAR, ENGINE.CAMERA_FAR);
37
+ followComponent.add(camera);
38
+ }
39
+ setupVicinityCheck() {
40
+ // Check every frame for nearby players using tick delegate
41
+ this.onTickPostPhysics.add(() => {
42
+ this.checkForNearbyPlayer();
43
+ });
44
+ }
45
+ checkForNearbyPlayer() {
46
+ const players = this.world.getActors(VehiclePlayer);
47
+ let foundNearbyPlayer = false;
48
+ for (const player of players) {
49
+ const distance = this.rootComponent.position.distanceTo(player.rootComponent.position);
50
+ if (distance <= this.interactionDistance) {
51
+ this.nearbyPlayer = player;
52
+ foundNearbyPlayer = true;
53
+ break;
54
+ }
55
+ }
56
+ if (!foundNearbyPlayer) {
57
+ this.nearbyPlayer = null;
58
+ }
59
+ }
60
+ canBeEntered() {
61
+ return this.nearbyPlayer !== null;
62
+ }
63
+ getNearbyPlayer() {
64
+ return this.nearbyPlayer;
65
+ }
66
+ setupExitHandler() {
67
+ // Add E key input handler for vehicle exit
68
+ this.onKeyDown.add((e) => {
69
+ if (e.key.toLowerCase() === 'e' && this.enteredPlayer) {
70
+ this.exitVehicle();
71
+ return true;
72
+ }
73
+ else if (e.key.toLowerCase() === 'f') {
74
+ if (this.movementComponent instanceof ENGINE.VehicleMovementComponent) {
75
+ this.movementComponent.flipVehicle(false);
76
+ }
77
+ return true;
78
+ }
79
+ return false;
80
+ });
81
+ }
82
+ setEnteredPlayer(player) {
83
+ this.enteredPlayer = player;
84
+ }
85
+ exitVehicle() {
86
+ if (!this.enteredPlayer)
87
+ return;
88
+ // Calculate exit position (to the side of the vehicle)
89
+ const exitPosition = this.calculateExitPosition();
90
+ // Get the current player controller
91
+ const controller = this.getPlayerController();
92
+ if (controller) {
93
+ // Move player to exit position
94
+ this.enteredPlayer.rootComponent.position.copy(exitPosition);
95
+ // Make player face the same direction as the vehicle (yaw only)
96
+ this.enteredPlayer.rootComponent.rotation.x = 0;
97
+ this.enteredPlayer.rootComponent.rotation.z = 0;
98
+ this.enteredPlayer.rootComponent.rotation.y = this.rootComponent.rotation.y;
99
+ // Restore player visibility and physics
100
+ this.enteredPlayer.rootComponent.visible = true;
101
+ // Only the root component has physics, do not propagate to children
102
+ this.enteredPlayer.rootComponent.setPhysicsEnabled(true, false);
103
+ // Switch possession back to player
104
+ controller.unpossess();
105
+ controller.possess(this.enteredPlayer);
106
+ // Clear entered player reference
107
+ this.enteredPlayer = null;
108
+ }
109
+ }
110
+ calculateExitPosition() {
111
+ // Calculate a position to the right side of the vehicle
112
+ const vehiclePosition = this.rootComponent.position.clone();
113
+ const vehicleRotation = this.rootComponent.rotation;
114
+ // Create a vector pointing to the right of the vehicle
115
+ const rightVector = new THREE.Vector3(1, 0, 0);
116
+ rightVector.applyEuler(vehicleRotation);
117
+ // Position the player 2 units to the right and slightly forward
118
+ const exitOffset = rightVector.multiplyScalar(2);
119
+ exitOffset.y = 1; // Raise slightly above ground
120
+ return vehiclePosition.add(exitOffset);
121
+ }
122
+ }
@@ -0,0 +1,33 @@
1
+ import * as ENGINE from 'genesys.js';
2
+ import * as THREE from 'three';
3
+ import './auto-imports.js';
4
+ import { VehiclePlayer } from './player.js';
5
+ import { UIHints } from './ui-hints.js';
6
+ class MyGame extends ENGINE.BaseGameLoop {
7
+ pawn = null;
8
+ controller = null;
9
+ createLoadingScreen() {
10
+ // enable the default loading screen
11
+ return new ENGINE.DefaultLoadingScreen();
12
+ }
13
+ async preStart() {
14
+ // default spawn location
15
+ const position = new THREE.Vector3(0, ENGINE.CHARACTER_HEIGHT / 2, 0);
16
+ // create the pawn
17
+ this.pawn = new VehiclePlayer({ position });
18
+ // create the controller and possess the pawn
19
+ this.controller = new ENGINE.PlayerController();
20
+ this.controller.possess(this.pawn);
21
+ // create UI hints
22
+ const uiHints = new UIHints();
23
+ // add all actors to the world
24
+ this.world.addActors(this.pawn, this.controller, uiHints);
25
+ }
26
+ }
27
+ export function main(container, gameId) {
28
+ const game = new MyGame(container, {
29
+ ...ENGINE.BaseGameLoop.DEFAULT_OPTIONS,
30
+ gameId
31
+ });
32
+ return game;
33
+ }
@@ -0,0 +1,189 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var MeshVehicle_1;
8
+ import * as ENGINE from 'genesys.js';
9
+ import * as THREE from 'three';
10
+ import { BaseVehicle } from './base-vehicle.js';
11
+ /**
12
+ * A vehicle that uses a 3D mesh model for visual representation
13
+ *
14
+ * Key points:
15
+ * - Uses invisible collision box for physics simulation (separate from visual mesh)
16
+ * - Loads GLB model for visual representation via GLTFMeshComponent
17
+ * - Movement parameters configured in createVehicleMovementComponent
18
+ * - No component is persisted (root is transient) in order to support recreating all the components in code (which is desired)
19
+ * - Do not create the builtin wheel mesh since the GLB models are used instead (createWheelMeshes = false)
20
+ * - Visual mesh is positioned and scaled to match collision box
21
+ * - Wheel mesh transforms are updated using the onWheelUpdated delegate
22
+ *
23
+ */
24
+ let MeshVehicle = MeshVehicle_1 = class MeshVehicle extends BaseVehicle {
25
+ constructor(options) {
26
+ // the root component is only used for collision and physics simulation
27
+ const rootComponent = new ENGINE.MeshComponent({
28
+ geometry: new THREE.BoxGeometry(2.77, 1.79, 5.75),
29
+ material: new THREE.MeshStandardMaterial({
30
+ color: 0x4444FF,
31
+ roughness: 0.7,
32
+ metalness: 0.3,
33
+ visible: false,
34
+ transparent: true,
35
+ opacity: 0.5,
36
+ }),
37
+ physicsOptions: {
38
+ enabled: true,
39
+ motionType: ENGINE.PhysicsMotionType.Dynamic,
40
+ generateCollisionEvents: true,
41
+ },
42
+ });
43
+ rootComponent.name = 'root';
44
+ options.rootComponent = rootComponent;
45
+ // mark the component as transient, this prevents all the components from being saved since we're recreating them in code
46
+ rootComponent.setTransient(true);
47
+ const chassisComponent = new ENGINE.GLTFMeshComponent({
48
+ modelUrl: '@project/assets/models/cyberTruck/chassis.glb',
49
+ position: new THREE.Vector3(0, 0, -0.75),
50
+ material: new THREE.MeshStandardMaterial({
51
+ color: 0x4444FF,
52
+ roughness: 0.7,
53
+ metalness: 0.3,
54
+ }),
55
+ physicsOptions: {
56
+ enabled: false,
57
+ }
58
+ });
59
+ chassisComponent.castShadow = true;
60
+ chassisComponent.name = 'chassis';
61
+ rootComponent.add(chassisComponent);
62
+ const wheelMeshes = [];
63
+ for (let i = 0; i < 4; i++) {
64
+ const wheelComponent = new ENGINE.GLTFMeshComponent({
65
+ modelUrl: '@project/assets/models/cyberTruck/wheel.glb',
66
+ material: new THREE.MeshStandardMaterial({
67
+ color: 0x44FF44,
68
+ roughness: 0.7,
69
+ metalness: 0.3,
70
+ }),
71
+ physicsOptions: {
72
+ enabled: false,
73
+ }
74
+ });
75
+ wheelComponent.castShadow = true;
76
+ wheelComponent.name = `wheel_${i}`;
77
+ wheelMeshes.push(wheelComponent);
78
+ }
79
+ rootComponent.add(...wheelMeshes);
80
+ const vehicleMovementComponent = MeshVehicle_1.createVehicleMovementComponent();
81
+ options.movementComponent = vehicleMovementComponent;
82
+ super(options);
83
+ const wheelComponents = this.getComponents(ENGINE.GLTFMeshComponent).filter(component => component.name.startsWith('wheel_'));
84
+ vehicleMovementComponent.onWheelUpdated.add((component, wheelIndex, wheelState) => {
85
+ // The first mesh component is the chassis component, so we need to skip it
86
+ const wheelMesh = wheelComponents[wheelIndex];
87
+ // Apply the final transformation to the wheel mesh
88
+ wheelMesh.position.copy(wheelState.relativePosition);
89
+ wheelMesh.quaternion.copy(wheelState.relativeQuaternion);
90
+ // Apply additional 180-degree rotation around Y-axis for wheels 0 and 2
91
+ if (wheelIndex === 0 || wheelIndex === 2) {
92
+ const yRotation = new THREE.Quaternion();
93
+ yRotation.setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI);
94
+ wheelMesh.quaternion.multiplyQuaternions(wheelMesh.quaternion, yRotation);
95
+ }
96
+ });
97
+ }
98
+ static createVehicleMovementComponent() {
99
+ const wheelBaseWidth = 3.2;
100
+ const wheelBaseLength = 3.8;
101
+ const wheelBaseHeight = -0.5;
102
+ const wheelRadius = 0.55;
103
+ const suspensionRestLength = 0.8;
104
+ const wheelWidth = 0.53;
105
+ const suspensionStiffness = 20;
106
+ const suspensionCompression = 1.83;
107
+ const suspensionRelaxation = 1.88;
108
+ const sideFrictionStiffness = 2;
109
+ const frictionSlip = 50;
110
+ // Create vehicle movement component
111
+ const vehicleMovement = new ENGINE.VehicleMovementComponent({
112
+ ...ENGINE.BasePawnMovementComponent.DEFAULT_OPTIONS,
113
+ createWheelMeshes: false,
114
+ maxEnginePower: 100,
115
+ maxBrakeForce: 1.5,
116
+ maxSteeringAngle: Math.PI / 6, // 30 degrees
117
+ engineResponseRate: 8.0,
118
+ steeringResponseRate: 12.0,
119
+ brakeResponseRate: 15.0,
120
+ wheelMaterialColor: 0x333333,
121
+ autoBreakWhenNotPossessed: 1,
122
+ autoStopBreak: 1,
123
+ wheels: [
124
+ // Default 4-wheel configuration
125
+ {
126
+ position: new THREE.Vector3(-wheelBaseWidth / 2, wheelBaseHeight, -wheelBaseLength / 2), // Front left
127
+ radius: wheelRadius,
128
+ width: wheelWidth,
129
+ canSteer: true,
130
+ isPowered: false,
131
+ canBrake: true,
132
+ suspensionRestLength,
133
+ suspensionStiffness,
134
+ suspensionCompression,
135
+ suspensionRelaxation,
136
+ sideFrictionStiffness,
137
+ frictionSlip,
138
+ },
139
+ {
140
+ position: new THREE.Vector3(wheelBaseWidth / 2, wheelBaseHeight, -wheelBaseLength / 2), // Front right
141
+ radius: wheelRadius,
142
+ width: wheelWidth,
143
+ canSteer: true,
144
+ isPowered: false,
145
+ canBrake: true,
146
+ suspensionRestLength,
147
+ suspensionStiffness,
148
+ suspensionCompression,
149
+ suspensionRelaxation,
150
+ sideFrictionStiffness,
151
+ frictionSlip,
152
+ },
153
+ {
154
+ position: new THREE.Vector3(-wheelBaseWidth / 2, wheelBaseHeight, wheelBaseLength / 2), // Rear left
155
+ radius: wheelRadius,
156
+ width: wheelWidth,
157
+ canSteer: false,
158
+ isPowered: true,
159
+ canBrake: true,
160
+ suspensionRestLength,
161
+ suspensionStiffness,
162
+ suspensionCompression,
163
+ suspensionRelaxation,
164
+ sideFrictionStiffness,
165
+ frictionSlip,
166
+ },
167
+ {
168
+ position: new THREE.Vector3(wheelBaseWidth / 2, wheelBaseHeight, wheelBaseLength / 2), // Rear right
169
+ radius: wheelRadius,
170
+ width: wheelWidth,
171
+ canSteer: false,
172
+ isPowered: true,
173
+ canBrake: true,
174
+ suspensionRestLength,
175
+ suspensionStiffness,
176
+ suspensionCompression,
177
+ suspensionRelaxation,
178
+ sideFrictionStiffness,
179
+ frictionSlip,
180
+ },
181
+ ],
182
+ });
183
+ return vehicleMovement;
184
+ }
185
+ };
186
+ MeshVehicle = MeshVehicle_1 = __decorate([
187
+ ENGINE.GameClass()
188
+ ], MeshVehicle);
189
+ export { MeshVehicle };
@@ -0,0 +1,102 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import * as ENGINE from 'genesys.js';
8
+ import * as THREE from 'three';
9
+ import { BaseVehicle } from './base-vehicle.js';
10
+ /**
11
+ * A vehicle player class.
12
+ *
13
+ * Key points:
14
+ * - No need to provide movementComponent and camera, they are created internally
15
+ * - The pawn is set to be transient so it's never saved in the level
16
+ * - The directional light follows the player for consistent shadows
17
+ *
18
+ */
19
+ let VehiclePlayer = class VehiclePlayer extends ENGINE.ThirdPersonCharacterPawn {
20
+ // Omit all the options that are created internally
21
+ constructor(options) {
22
+ // simple camera component - contains a perspective camera by default
23
+ const camera = new THREE.PerspectiveCamera(ENGINE.CAMERA_FOV, 1, 0.1, 1000);
24
+ // set camera position for third person view
25
+ camera.position.set(0, ENGINE.CHARACTER_HEIGHT * 1.3, ENGINE.CHARACTER_HEIGHT * 2);
26
+ camera.lookAt(0, 0, 0);
27
+ // use capsule root component for collision
28
+ const rootComponent = new ENGINE.MeshComponent({
29
+ geometry: ENGINE.GameBuilder.createDefaultPawnCapsuleGeometry(),
30
+ material: new THREE.MeshStandardMaterial({ color: ENGINE.Color.YELLOW, visible: false, transparent: true, opacity: 0.5 }),
31
+ physicsOptions: {
32
+ enabled: true,
33
+ // KinematicVelocityBased is required to use the physics character controller
34
+ motionType: ENGINE.PhysicsMotionType.KinematicVelocityBased,
35
+ collisionProfile: ENGINE.DefaultCollisionProfile.Character,
36
+ },
37
+ });
38
+ // use third person movement mechanics
39
+ const movementComponent = new ENGINE.CharacterMovementComponent({
40
+ ...ENGINE.CharacterMovementComponent.DEFAULT_OPTIONS,
41
+ movementType: ENGINE.CharacterMovementType.ThirdPerson,
42
+ });
43
+ // construct the pawn
44
+ super({
45
+ ...options,
46
+ rootComponent,
47
+ movementComponent,
48
+ camera,
49
+ // make sure the directional light follows the player for consistent shadows
50
+ enableDirectionalLightFollowing: true,
51
+ modelUrl: '@engine/assets/character/mannequinG.glb',
52
+ configUrl: '@engine/assets/character/config/mannequin-anim.json',
53
+ meshPosition: new THREE.Vector3(0, -ENGINE.CHARACTER_HEIGHT / 2, 0),
54
+ meshRotation: new THREE.Euler(0, Math.PI, 0),
55
+ meshScale: new THREE.Vector3(1, 1, 1),
56
+ });
57
+ // set the pawn to be transient so it's never saved in the level
58
+ this.setTransient(true);
59
+ }
60
+ async doBeginPlay() {
61
+ await super.doBeginPlay();
62
+ this.setupVehicleInteraction();
63
+ }
64
+ setupVehicleInteraction() {
65
+ // Add E key input handler for vehicle possession
66
+ this.onKeyDown.add((e) => {
67
+ if (e.key.toLowerCase() === 'e') {
68
+ this.tryEnterVehicle();
69
+ return true;
70
+ }
71
+ return false;
72
+ });
73
+ }
74
+ tryEnterVehicle() {
75
+ // Find nearby vehicles that can be entered
76
+ const vehicles = this.world.getActors(BaseVehicle);
77
+ for (const vehicle of vehicles) {
78
+ if (vehicle.canBeEntered() && vehicle.getNearbyPlayer() === this) {
79
+ this.enterVehicle(vehicle);
80
+ break;
81
+ }
82
+ }
83
+ }
84
+ enterVehicle(vehicle) {
85
+ // Get the current player controller
86
+ const controller = this.getPlayerController();
87
+ if (controller) {
88
+ // Set this player as the entered player in the vehicle
89
+ vehicle.setEnteredPlayer(this);
90
+ // Unpossess current pawn and possess the vehicle
91
+ controller.unpossess();
92
+ controller.possess(vehicle);
93
+ // Hide the player character
94
+ this.rootComponent.visible = false;
95
+ this.rootComponent.setPhysicsEnabled(false);
96
+ }
97
+ }
98
+ };
99
+ VehiclePlayer = __decorate([
100
+ ENGINE.GameClass()
101
+ ], VehiclePlayer);
102
+ export { VehiclePlayer };