@directivegames/genesys.sdk 3.2.2 → 3.2.4

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 (82) hide show
  1. package/README.md +60 -60
  2. package/dist/src/core/cli.js +22 -22
  3. package/dist/src/templates/scripts/genesys/genesys-mcp.js +25 -25
  4. package/dist/src/templates/scripts/genesys/mcp/editor-functions.js +4 -4
  5. package/dist/src/templates/src/templates/vehicle/src/ui-hints.js +30 -30
  6. package/package.json +176 -176
  7. package/scripts/post-install.ts +143 -143
  8. package/src/asset-pack/.gitattributes +88 -88
  9. package/src/asset-pack/eslint.config.js +45 -45
  10. package/src/asset-pack/gitignore +11 -11
  11. package/src/asset-pack/scripts/postinstall.ts +81 -81
  12. package/src/asset-pack/tsconfig.json +33 -33
  13. package/src/templates/.cursor/mcp.json +20 -20
  14. package/src/templates/.cursorignore +2 -2
  15. package/src/templates/.gitattributes +88 -88
  16. package/src/templates/.vscode/settings.json +6 -6
  17. package/src/templates/AGENTS.md +86 -86
  18. package/src/templates/README.md +24 -24
  19. package/src/templates/eslint.config.js +45 -45
  20. package/src/templates/gitignore +11 -11
  21. package/src/templates/index.html +34 -34
  22. package/src/templates/pnpm-lock.yaml +3676 -3676
  23. package/src/templates/scripts/genesys/build-project.ts +51 -51
  24. package/src/templates/scripts/genesys/calc-bounding-box.ts +272 -272
  25. package/src/templates/scripts/genesys/common.ts +46 -46
  26. package/src/templates/scripts/genesys/const.ts +9 -9
  27. package/src/templates/scripts/genesys/dev/dump-default-scene.ts +11 -11
  28. package/src/templates/scripts/genesys/dev/generate-manifest.ts +146 -146
  29. package/src/templates/scripts/genesys/dev/launcher.ts +46 -46
  30. package/src/templates/scripts/genesys/dev/storage-provider.ts +229 -229
  31. package/src/templates/scripts/genesys/dev/update-template-scenes.ts +84 -84
  32. package/src/templates/scripts/genesys/doc-server.ts +16 -16
  33. package/src/templates/scripts/genesys/genesys-mcp.ts +526 -526
  34. package/src/templates/scripts/genesys/mcp/doc-tools.ts +86 -86
  35. package/src/templates/scripts/genesys/mcp/editor-functions.ts +151 -151
  36. package/src/templates/scripts/genesys/mcp/editor-tools.ts +73 -73
  37. package/src/templates/scripts/genesys/mcp/get-scene-state.ts +35 -35
  38. package/src/templates/scripts/genesys/mcp/run-subprocess.ts +30 -30
  39. package/src/templates/scripts/genesys/mcp/search-actors.ts +858 -858
  40. package/src/templates/scripts/genesys/mcp/search-assets.ts +380 -380
  41. package/src/templates/scripts/genesys/mcp/utils.ts +281 -281
  42. package/src/templates/scripts/genesys/misc.ts +42 -42
  43. package/src/templates/scripts/genesys/mock.ts +6 -6
  44. package/src/templates/scripts/genesys/place-actors.ts +179 -179
  45. package/src/templates/scripts/genesys/post-install.ts +30 -30
  46. package/src/templates/scripts/genesys/prefab.schema.json +84 -84
  47. package/src/templates/scripts/genesys/remove-engine-comments.ts +134 -134
  48. package/src/templates/scripts/genesys/run-mcp-inspector.bat +4 -4
  49. package/src/templates/scripts/genesys/storageProvider.ts +182 -182
  50. package/src/templates/scripts/genesys/validate-prefabs.ts +138 -138
  51. package/src/templates/src/index.ts +22 -22
  52. package/src/templates/src/templates/firstPerson/assets/default.genesys-scene +165 -165
  53. package/src/templates/src/templates/firstPerson/src/game.ts +39 -39
  54. package/src/templates/src/templates/firstPerson/src/player.ts +63 -63
  55. package/src/templates/src/templates/fps/assets/default.genesys-scene +9459 -9459
  56. package/src/templates/src/templates/fps/src/game.ts +39 -39
  57. package/src/templates/src/templates/fps/src/player.ts +69 -69
  58. package/src/templates/src/templates/fps/src/weapon.ts +54 -54
  59. package/src/templates/src/templates/freeCamera/assets/default.genesys-scene +165 -165
  60. package/src/templates/src/templates/freeCamera/src/game.ts +39 -39
  61. package/src/templates/src/templates/freeCamera/src/player.ts +45 -45
  62. package/src/templates/src/templates/sideScroller/assets/default.genesys-scene +121 -121
  63. package/src/templates/src/templates/sideScroller/src/const.ts +45 -45
  64. package/src/templates/src/templates/sideScroller/src/game.ts +122 -122
  65. package/src/templates/src/templates/sideScroller/src/level-generator.ts +361 -361
  66. package/src/templates/src/templates/sideScroller/src/player.ts +125 -125
  67. package/src/templates/src/templates/thirdPerson/assets/default.genesys-scene +165 -165
  68. package/src/templates/src/templates/thirdPerson/src/game.ts +39 -39
  69. package/src/templates/src/templates/thirdPerson/src/player.ts +61 -61
  70. package/src/templates/src/templates/vehicle/assets/default.genesys-scene +225 -225
  71. package/src/templates/src/templates/vehicle/src/base-vehicle.ts +145 -145
  72. package/src/templates/src/templates/vehicle/src/game.ts +43 -43
  73. package/src/templates/src/templates/vehicle/src/mesh-vehicle.ts +191 -191
  74. package/src/templates/src/templates/vehicle/src/player.ts +109 -109
  75. package/src/templates/src/templates/vehicle/src/primitive-vehicle.ts +266 -266
  76. package/src/templates/src/templates/vehicle/src/ui-hints.ts +101 -101
  77. package/src/templates/src/templates/vr-game/assets/default.genesys-scene +246 -246
  78. package/src/templates/src/templates/vr-game/src/auto-imports.ts +1 -1
  79. package/src/templates/src/templates/vr-game/src/game.ts +66 -66
  80. package/src/templates/src/templates/vr-game/src/sample-vr-actor.ts +26 -26
  81. package/src/templates/tsconfig.json +34 -34
  82. package/src/templates/vite.config.ts +52 -52
@@ -1,191 +1,191 @@
1
- import * as ENGINE from 'genesys.js';
2
- import * as THREE from 'three';
3
-
4
- import { BaseVehicle } from './base-vehicle.js';
5
-
6
- /**
7
- * A vehicle that uses a 3D mesh model for visual representation
8
- *
9
- * Key points:
10
- * - Uses invisible collision box for physics simulation (separate from visual mesh)
11
- * - Loads GLB model for visual representation via GLTFMeshComponent
12
- * - Movement parameters configured in createVehicleMovementComponent
13
- * - No component is persisted (root is transient) in order to support recreating all the components in code (which is desired)
14
- * - Do not create the builtin wheel mesh since the GLB models are used instead (createWheelMeshes = false)
15
- * - Visual mesh is positioned and scaled to match collision box
16
- * - Wheel mesh transforms are updated using the onWheelUpdated delegate
17
- *
18
- */
19
- @ENGINE.GameClass()
20
- export class MeshVehicle extends BaseVehicle {
21
- constructor(options: ENGINE.PawnOptions) {
22
- // the root component is only used for collision and physics simulation
23
- const rootComponent = new ENGINE.MeshComponent({
24
- geometry: new THREE.BoxGeometry(2.77, 1.79, 5.75),
25
- material: new THREE.MeshStandardMaterial({
26
- color: 0x4444FF,
27
- roughness: 0.7,
28
- metalness: 0.3,
29
- visible: false,
30
- transparent: true,
31
- opacity: 0.5,
32
- }),
33
- physicsOptions: {
34
- enabled: true,
35
- motionType: ENGINE.PhysicsMotionType.Dynamic,
36
- generateCollisionEvents: true,
37
- },
38
- });
39
- rootComponent.name = 'root';
40
- options.rootComponent = rootComponent;
41
- // mark the component as transient, this prevents all the components from being saved since we're recreating them in code
42
- rootComponent.setTransient(true);
43
-
44
- const chassisComponent = new ENGINE.GLTFMeshComponent({
45
- modelUrl: '@project/assets/models/cyberTruck/chassis.glb',
46
- position: new THREE.Vector3(0, 0, -0.75),
47
- material: new THREE.MeshStandardMaterial({
48
- color: 0x4444FF,
49
- roughness: 0.7,
50
- metalness: 0.3,
51
- }),
52
- physicsOptions: {
53
- enabled: false,
54
- }
55
- });
56
- chassisComponent.castShadow = true;
57
- chassisComponent.name = 'chassis';
58
- rootComponent.add(chassisComponent);
59
-
60
- const wheelMeshes: ENGINE.GLTFMeshComponent[] = [];
61
- for (let i = 0; i < 4; i++) {
62
- const wheelComponent = new ENGINE.GLTFMeshComponent({
63
- modelUrl: '@project/assets/models/cyberTruck/wheel.glb',
64
- material: new THREE.MeshStandardMaterial({
65
- color: 0x44FF44,
66
- roughness: 0.7,
67
- metalness: 0.3,
68
- }),
69
- physicsOptions: {
70
- enabled: false,
71
- }
72
- });
73
- wheelComponent.castShadow = true;
74
- wheelComponent.name = `wheel_${i}`;
75
- wheelMeshes.push(wheelComponent);
76
- }
77
- rootComponent.add(...wheelMeshes);
78
- const vehicleMovementComponent = MeshVehicle.createVehicleMovementComponent();
79
-
80
- options.movementComponent = vehicleMovementComponent;
81
-
82
- super(options);
83
-
84
- const wheelComponents = this.getComponents(ENGINE.GLTFMeshComponent).filter(component => component.name.startsWith('wheel_'));
85
-
86
- vehicleMovementComponent.onWheelUpdated.add((component, wheelIndex, wheelState) => {
87
- // The first mesh component is the chassis component, so we need to skip it
88
- const wheelMesh = wheelComponents[wheelIndex];
89
-
90
- // Apply the final transformation to the wheel mesh
91
- wheelMesh.position.copy(wheelState.relativePosition);
92
- wheelMesh.quaternion.copy(wheelState.relativeQuaternion);
93
-
94
- // Apply additional 180-degree rotation around Y-axis for wheels 0 and 2
95
- if (wheelIndex === 0 || wheelIndex === 2) {
96
- const yRotation = new THREE.Quaternion();
97
- yRotation.setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI);
98
- wheelMesh.quaternion.multiplyQuaternions(wheelMesh.quaternion, yRotation);
99
- }
100
- });
101
- }
102
-
103
- static createVehicleMovementComponent(): ENGINE.VehicleMovementComponent {
104
- const wheelBaseWidth = 3.2;
105
- const wheelBaseLength = 3.8;
106
- const wheelBaseHeight = -0.5;
107
- const wheelRadius = 0.55;
108
- const suspensionRestLength = 0.8;
109
- const wheelWidth = 0.53;
110
- const suspensionStiffness = 20;
111
- const suspensionCompression = 1.83;
112
- const suspensionRelaxation = 1.88;
113
- const sideFrictionStiffness = 2;
114
- const frictionSlip = 50;
115
-
116
- // Create vehicle movement component
117
- const vehicleMovement = new ENGINE.VehicleMovementComponent({
118
- ...ENGINE.BasePawnMovementComponent.DEFAULT_OPTIONS,
119
- createWheelMeshes: false,
120
- maxEnginePower: 100,
121
- maxBrakeForce: 1.5,
122
- maxSteeringAngle: Math.PI / 6, // 30 degrees
123
- engineResponseRate: 8.0,
124
- steeringResponseRate: 12.0,
125
- brakeResponseRate: 15.0,
126
- wheelMaterialColor: 0x333333,
127
- autoBreakWhenNotPossessed: 1,
128
- autoStopBreak: 1,
129
- wheels: [
130
- // Default 4-wheel configuration
131
- {
132
- position: new THREE.Vector3(-wheelBaseWidth / 2, wheelBaseHeight, -wheelBaseLength / 2), // Front left
133
- radius: wheelRadius,
134
- width: wheelWidth,
135
- canSteer: true,
136
- isPowered: false,
137
- canBrake: true,
138
- suspensionRestLength,
139
- suspensionStiffness,
140
- suspensionCompression,
141
- suspensionRelaxation,
142
- sideFrictionStiffness,
143
- frictionSlip,
144
- },
145
- {
146
- position: new THREE.Vector3(wheelBaseWidth / 2, wheelBaseHeight, -wheelBaseLength / 2), // Front right
147
- radius: wheelRadius,
148
- width: wheelWidth,
149
- canSteer: true,
150
- isPowered: false,
151
- canBrake: true,
152
- suspensionRestLength,
153
- suspensionStiffness,
154
- suspensionCompression,
155
- suspensionRelaxation,
156
- sideFrictionStiffness,
157
- frictionSlip,
158
- },
159
- {
160
- position: new THREE.Vector3(-wheelBaseWidth / 2, wheelBaseHeight, wheelBaseLength / 2), // Rear left
161
- radius: wheelRadius,
162
- width: wheelWidth,
163
- canSteer: false,
164
- isPowered: true,
165
- canBrake: true,
166
- suspensionRestLength,
167
- suspensionStiffness,
168
- suspensionCompression,
169
- suspensionRelaxation,
170
- sideFrictionStiffness,
171
- frictionSlip,
172
- },
173
- {
174
- position: new THREE.Vector3(wheelBaseWidth / 2, wheelBaseHeight, wheelBaseLength / 2), // Rear right
175
- radius: wheelRadius,
176
- width: wheelWidth,
177
- canSteer: false,
178
- isPowered: true,
179
- canBrake: true,
180
- suspensionRestLength,
181
- suspensionStiffness,
182
- suspensionCompression,
183
- suspensionRelaxation,
184
- sideFrictionStiffness,
185
- frictionSlip,
186
- },
187
- ],
188
- });
189
- return vehicleMovement;
190
- }
191
- }
1
+ import * as ENGINE from 'genesys.js';
2
+ import * as THREE from 'three';
3
+
4
+ import { BaseVehicle } from './base-vehicle.js';
5
+
6
+ /**
7
+ * A vehicle that uses a 3D mesh model for visual representation
8
+ *
9
+ * Key points:
10
+ * - Uses invisible collision box for physics simulation (separate from visual mesh)
11
+ * - Loads GLB model for visual representation via GLTFMeshComponent
12
+ * - Movement parameters configured in createVehicleMovementComponent
13
+ * - No component is persisted (root is transient) in order to support recreating all the components in code (which is desired)
14
+ * - Do not create the builtin wheel mesh since the GLB models are used instead (createWheelMeshes = false)
15
+ * - Visual mesh is positioned and scaled to match collision box
16
+ * - Wheel mesh transforms are updated using the onWheelUpdated delegate
17
+ *
18
+ */
19
+ @ENGINE.GameClass()
20
+ export class MeshVehicle extends BaseVehicle {
21
+ constructor(options: ENGINE.PawnOptions) {
22
+ // the root component is only used for collision and physics simulation
23
+ const rootComponent = new ENGINE.MeshComponent({
24
+ geometry: new THREE.BoxGeometry(2.77, 1.79, 5.75),
25
+ material: new THREE.MeshStandardMaterial({
26
+ color: 0x4444FF,
27
+ roughness: 0.7,
28
+ metalness: 0.3,
29
+ visible: false,
30
+ transparent: true,
31
+ opacity: 0.5,
32
+ }),
33
+ physicsOptions: {
34
+ enabled: true,
35
+ motionType: ENGINE.PhysicsMotionType.Dynamic,
36
+ generateCollisionEvents: true,
37
+ },
38
+ });
39
+ rootComponent.name = 'root';
40
+ options.rootComponent = rootComponent;
41
+ // mark the component as transient, this prevents all the components from being saved since we're recreating them in code
42
+ rootComponent.setTransient(true);
43
+
44
+ const chassisComponent = new ENGINE.GLTFMeshComponent({
45
+ modelUrl: '@project/assets/models/cyberTruck/chassis.glb',
46
+ position: new THREE.Vector3(0, 0, -0.75),
47
+ material: new THREE.MeshStandardMaterial({
48
+ color: 0x4444FF,
49
+ roughness: 0.7,
50
+ metalness: 0.3,
51
+ }),
52
+ physicsOptions: {
53
+ enabled: false,
54
+ }
55
+ });
56
+ chassisComponent.castShadow = true;
57
+ chassisComponent.name = 'chassis';
58
+ rootComponent.add(chassisComponent);
59
+
60
+ const wheelMeshes: ENGINE.GLTFMeshComponent[] = [];
61
+ for (let i = 0; i < 4; i++) {
62
+ const wheelComponent = new ENGINE.GLTFMeshComponent({
63
+ modelUrl: '@project/assets/models/cyberTruck/wheel.glb',
64
+ material: new THREE.MeshStandardMaterial({
65
+ color: 0x44FF44,
66
+ roughness: 0.7,
67
+ metalness: 0.3,
68
+ }),
69
+ physicsOptions: {
70
+ enabled: false,
71
+ }
72
+ });
73
+ wheelComponent.castShadow = true;
74
+ wheelComponent.name = `wheel_${i}`;
75
+ wheelMeshes.push(wheelComponent);
76
+ }
77
+ rootComponent.add(...wheelMeshes);
78
+ const vehicleMovementComponent = MeshVehicle.createVehicleMovementComponent();
79
+
80
+ options.movementComponent = vehicleMovementComponent;
81
+
82
+ super(options);
83
+
84
+ const wheelComponents = this.getComponents(ENGINE.GLTFMeshComponent).filter(component => component.name.startsWith('wheel_'));
85
+
86
+ vehicleMovementComponent.onWheelUpdated.add((component, wheelIndex, wheelState) => {
87
+ // The first mesh component is the chassis component, so we need to skip it
88
+ const wheelMesh = wheelComponents[wheelIndex];
89
+
90
+ // Apply the final transformation to the wheel mesh
91
+ wheelMesh.position.copy(wheelState.relativePosition);
92
+ wheelMesh.quaternion.copy(wheelState.relativeQuaternion);
93
+
94
+ // Apply additional 180-degree rotation around Y-axis for wheels 0 and 2
95
+ if (wheelIndex === 0 || wheelIndex === 2) {
96
+ const yRotation = new THREE.Quaternion();
97
+ yRotation.setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI);
98
+ wheelMesh.quaternion.multiplyQuaternions(wheelMesh.quaternion, yRotation);
99
+ }
100
+ });
101
+ }
102
+
103
+ static createVehicleMovementComponent(): ENGINE.VehicleMovementComponent {
104
+ const wheelBaseWidth = 3.2;
105
+ const wheelBaseLength = 3.8;
106
+ const wheelBaseHeight = -0.5;
107
+ const wheelRadius = 0.55;
108
+ const suspensionRestLength = 0.8;
109
+ const wheelWidth = 0.53;
110
+ const suspensionStiffness = 20;
111
+ const suspensionCompression = 1.83;
112
+ const suspensionRelaxation = 1.88;
113
+ const sideFrictionStiffness = 2;
114
+ const frictionSlip = 50;
115
+
116
+ // Create vehicle movement component
117
+ const vehicleMovement = new ENGINE.VehicleMovementComponent({
118
+ ...ENGINE.BasePawnMovementComponent.DEFAULT_OPTIONS,
119
+ createWheelMeshes: false,
120
+ maxEnginePower: 100,
121
+ maxBrakeForce: 1.5,
122
+ maxSteeringAngle: Math.PI / 6, // 30 degrees
123
+ engineResponseRate: 8.0,
124
+ steeringResponseRate: 12.0,
125
+ brakeResponseRate: 15.0,
126
+ wheelMaterialColor: 0x333333,
127
+ autoBreakWhenNotPossessed: 1,
128
+ autoStopBreak: 1,
129
+ wheels: [
130
+ // Default 4-wheel configuration
131
+ {
132
+ position: new THREE.Vector3(-wheelBaseWidth / 2, wheelBaseHeight, -wheelBaseLength / 2), // Front left
133
+ radius: wheelRadius,
134
+ width: wheelWidth,
135
+ canSteer: true,
136
+ isPowered: false,
137
+ canBrake: true,
138
+ suspensionRestLength,
139
+ suspensionStiffness,
140
+ suspensionCompression,
141
+ suspensionRelaxation,
142
+ sideFrictionStiffness,
143
+ frictionSlip,
144
+ },
145
+ {
146
+ position: new THREE.Vector3(wheelBaseWidth / 2, wheelBaseHeight, -wheelBaseLength / 2), // Front right
147
+ radius: wheelRadius,
148
+ width: wheelWidth,
149
+ canSteer: true,
150
+ isPowered: false,
151
+ canBrake: true,
152
+ suspensionRestLength,
153
+ suspensionStiffness,
154
+ suspensionCompression,
155
+ suspensionRelaxation,
156
+ sideFrictionStiffness,
157
+ frictionSlip,
158
+ },
159
+ {
160
+ position: new THREE.Vector3(-wheelBaseWidth / 2, wheelBaseHeight, wheelBaseLength / 2), // Rear left
161
+ radius: wheelRadius,
162
+ width: wheelWidth,
163
+ canSteer: false,
164
+ isPowered: true,
165
+ canBrake: true,
166
+ suspensionRestLength,
167
+ suspensionStiffness,
168
+ suspensionCompression,
169
+ suspensionRelaxation,
170
+ sideFrictionStiffness,
171
+ frictionSlip,
172
+ },
173
+ {
174
+ position: new THREE.Vector3(wheelBaseWidth / 2, wheelBaseHeight, wheelBaseLength / 2), // Rear right
175
+ radius: wheelRadius,
176
+ width: wheelWidth,
177
+ canSteer: false,
178
+ isPowered: true,
179
+ canBrake: true,
180
+ suspensionRestLength,
181
+ suspensionStiffness,
182
+ suspensionCompression,
183
+ suspensionRelaxation,
184
+ sideFrictionStiffness,
185
+ frictionSlip,
186
+ },
187
+ ],
188
+ });
189
+ return vehicleMovement;
190
+ }
191
+ }
@@ -1,109 +1,109 @@
1
- import * as ENGINE from 'genesys.js';
2
- import * as THREE from 'three';
3
-
4
- import { BaseVehicle } from './base-vehicle.js';
5
-
6
-
7
- /**
8
- * A vehicle player class.
9
- *
10
- * Key points:
11
- * - No need to provide movementComponent and camera, they are created internally
12
- * - The pawn is set to be transient so it's never saved in the level
13
- * - The directional light follows the player for consistent shadows
14
- *
15
- */
16
- @ENGINE.GameClass()
17
- export class VehiclePlayer extends ENGINE.ThirdPersonCharacterPawn {
18
- // Omit all the options that are created internally
19
- constructor(options: Omit<ENGINE.ThirdPersonCharacterPawnOptions,
20
- 'rootComponent' | 'movementComponent' | 'camera' | 'modelUrl' | 'configUrl' | 'meshPosition' | 'meshRotation' | 'meshScale'>) {
21
- // simple camera component - contains a perspective camera by default
22
- const camera = new THREE.PerspectiveCamera(ENGINE.CAMERA_FOV, 1, 0.1, 1000);
23
- // set camera position for third person view
24
- camera.position.set(0, ENGINE.CHARACTER_HEIGHT * 1.3, ENGINE.CHARACTER_HEIGHT * 2);
25
- camera.lookAt(0, 0, 0);
26
-
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
-
39
- // use third person movement mechanics
40
- const movementComponent = new ENGINE.CharacterMovementComponent({
41
- ...ENGINE.CharacterMovementComponent.DEFAULT_OPTIONS,
42
- movementType: ENGINE.CharacterMovementType.ThirdPerson,
43
- });
44
-
45
- // construct the pawn
46
- super({
47
- ...options,
48
- rootComponent,
49
- movementComponent,
50
- camera,
51
- // make sure the directional light follows the player for consistent shadows
52
- enableDirectionalLightFollowing: true,
53
- modelUrl: '@engine/assets/character/mannequinG.glb',
54
- configUrl: '@engine/assets/character/config/mannequin-anim.json',
55
- meshPosition: new THREE.Vector3(0, -ENGINE.CHARACTER_HEIGHT / 2, 0),
56
- meshRotation: new THREE.Euler(0, Math.PI, 0),
57
- meshScale: new THREE.Vector3(1, 1, 1),
58
- });
59
-
60
- // set the pawn to be transient so it's never saved in the level
61
- this.setTransient(true);
62
- }
63
-
64
- protected override async doBeginPlay(): Promise<void> {
65
- await super.doBeginPlay();
66
- this.setupVehicleInteraction();
67
- }
68
-
69
- protected setupVehicleInteraction(): void {
70
- // Add E key input handler for vehicle possession
71
- this.onKeyDown.add((e: KeyboardEvent) => {
72
- if (e.key.toLowerCase() === 'e') {
73
- this.tryEnterVehicle();
74
- return true;
75
- }
76
- return false;
77
- });
78
- }
79
-
80
- protected tryEnterVehicle(): void {
81
- // Find nearby vehicles that can be entered
82
- const vehicles = this.world!.getActors(BaseVehicle);
83
-
84
- for (const vehicle of vehicles) {
85
- if (vehicle.canBeEntered() && vehicle.getNearbyPlayer() === this) {
86
- this.enterVehicle(vehicle);
87
- break;
88
- }
89
- }
90
- }
91
-
92
- protected enterVehicle(vehicle: BaseVehicle): void {
93
- // Get the current player controller
94
- const controller = this.getPlayerController();
95
-
96
- if (controller) {
97
- // Set this player as the entered player in the vehicle
98
- vehicle.setEnteredPlayer(this);
99
-
100
- // Unpossess current pawn and possess the vehicle
101
- controller.unpossess();
102
- controller.possess(vehicle);
103
-
104
- // Hide the player character
105
- this.rootComponent.visible = false;
106
- this.rootComponent.setPhysicsEnabled(false);
107
- }
108
- }
109
- }
1
+ import * as ENGINE from 'genesys.js';
2
+ import * as THREE from 'three';
3
+
4
+ import { BaseVehicle } from './base-vehicle.js';
5
+
6
+
7
+ /**
8
+ * A vehicle player class.
9
+ *
10
+ * Key points:
11
+ * - No need to provide movementComponent and camera, they are created internally
12
+ * - The pawn is set to be transient so it's never saved in the level
13
+ * - The directional light follows the player for consistent shadows
14
+ *
15
+ */
16
+ @ENGINE.GameClass()
17
+ export class VehiclePlayer extends ENGINE.ThirdPersonCharacterPawn {
18
+ // Omit all the options that are created internally
19
+ constructor(options: Omit<ENGINE.ThirdPersonCharacterPawnOptions,
20
+ 'rootComponent' | 'movementComponent' | 'camera' | 'modelUrl' | 'configUrl' | 'meshPosition' | 'meshRotation' | 'meshScale'>) {
21
+ // simple camera component - contains a perspective camera by default
22
+ const camera = new THREE.PerspectiveCamera(ENGINE.CAMERA_FOV, 1, 0.1, 1000);
23
+ // set camera position for third person view
24
+ camera.position.set(0, ENGINE.CHARACTER_HEIGHT * 1.3, ENGINE.CHARACTER_HEIGHT * 2);
25
+ camera.lookAt(0, 0, 0);
26
+
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
+
39
+ // use third person movement mechanics
40
+ const movementComponent = new ENGINE.CharacterMovementComponent({
41
+ ...ENGINE.CharacterMovementComponent.DEFAULT_OPTIONS,
42
+ movementType: ENGINE.CharacterMovementType.ThirdPerson,
43
+ });
44
+
45
+ // construct the pawn
46
+ super({
47
+ ...options,
48
+ rootComponent,
49
+ movementComponent,
50
+ camera,
51
+ // make sure the directional light follows the player for consistent shadows
52
+ enableDirectionalLightFollowing: true,
53
+ modelUrl: '@engine/assets/character/mannequinG.glb',
54
+ configUrl: '@engine/assets/character/config/mannequin-anim.json',
55
+ meshPosition: new THREE.Vector3(0, -ENGINE.CHARACTER_HEIGHT / 2, 0),
56
+ meshRotation: new THREE.Euler(0, Math.PI, 0),
57
+ meshScale: new THREE.Vector3(1, 1, 1),
58
+ });
59
+
60
+ // set the pawn to be transient so it's never saved in the level
61
+ this.setTransient(true);
62
+ }
63
+
64
+ protected override async doBeginPlay(): Promise<void> {
65
+ await super.doBeginPlay();
66
+ this.setupVehicleInteraction();
67
+ }
68
+
69
+ protected setupVehicleInteraction(): void {
70
+ // Add E key input handler for vehicle possession
71
+ this.onKeyDown.add((e: KeyboardEvent) => {
72
+ if (e.key.toLowerCase() === 'e') {
73
+ this.tryEnterVehicle();
74
+ return true;
75
+ }
76
+ return false;
77
+ });
78
+ }
79
+
80
+ protected tryEnterVehicle(): void {
81
+ // Find nearby vehicles that can be entered
82
+ const vehicles = this.world!.getActors(BaseVehicle);
83
+
84
+ for (const vehicle of vehicles) {
85
+ if (vehicle.canBeEntered() && vehicle.getNearbyPlayer() === this) {
86
+ this.enterVehicle(vehicle);
87
+ break;
88
+ }
89
+ }
90
+ }
91
+
92
+ protected enterVehicle(vehicle: BaseVehicle): void {
93
+ // Get the current player controller
94
+ const controller = this.getPlayerController();
95
+
96
+ if (controller) {
97
+ // Set this player as the entered player in the vehicle
98
+ vehicle.setEnteredPlayer(this);
99
+
100
+ // Unpossess current pawn and possess the vehicle
101
+ controller.unpossess();
102
+ controller.possess(vehicle);
103
+
104
+ // Hide the player character
105
+ this.rootComponent.visible = false;
106
+ this.rootComponent.setPhysicsEnabled(false);
107
+ }
108
+ }
109
+ }