@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.
- package/README.md +60 -60
- package/dist/src/core/cli.js +22 -22
- package/dist/src/templates/scripts/genesys/genesys-mcp.js +25 -25
- package/dist/src/templates/scripts/genesys/mcp/editor-functions.js +4 -4
- package/dist/src/templates/src/templates/vehicle/src/ui-hints.js +30 -30
- package/package.json +176 -176
- package/scripts/post-install.ts +143 -143
- package/src/asset-pack/.gitattributes +88 -88
- package/src/asset-pack/eslint.config.js +45 -45
- package/src/asset-pack/gitignore +11 -11
- package/src/asset-pack/scripts/postinstall.ts +81 -81
- package/src/asset-pack/tsconfig.json +33 -33
- package/src/templates/.cursor/mcp.json +20 -20
- package/src/templates/.cursorignore +2 -2
- package/src/templates/.gitattributes +88 -88
- package/src/templates/.vscode/settings.json +6 -6
- package/src/templates/AGENTS.md +86 -86
- package/src/templates/README.md +24 -24
- package/src/templates/eslint.config.js +45 -45
- package/src/templates/gitignore +11 -11
- package/src/templates/index.html +34 -34
- package/src/templates/pnpm-lock.yaml +3676 -3676
- package/src/templates/scripts/genesys/build-project.ts +51 -51
- package/src/templates/scripts/genesys/calc-bounding-box.ts +272 -272
- package/src/templates/scripts/genesys/common.ts +46 -46
- package/src/templates/scripts/genesys/const.ts +9 -9
- package/src/templates/scripts/genesys/dev/dump-default-scene.ts +11 -11
- package/src/templates/scripts/genesys/dev/generate-manifest.ts +146 -146
- package/src/templates/scripts/genesys/dev/launcher.ts +46 -46
- package/src/templates/scripts/genesys/dev/storage-provider.ts +229 -229
- package/src/templates/scripts/genesys/dev/update-template-scenes.ts +84 -84
- package/src/templates/scripts/genesys/doc-server.ts +16 -16
- package/src/templates/scripts/genesys/genesys-mcp.ts +526 -526
- package/src/templates/scripts/genesys/mcp/doc-tools.ts +86 -86
- package/src/templates/scripts/genesys/mcp/editor-functions.ts +151 -151
- package/src/templates/scripts/genesys/mcp/editor-tools.ts +73 -73
- package/src/templates/scripts/genesys/mcp/get-scene-state.ts +35 -35
- package/src/templates/scripts/genesys/mcp/run-subprocess.ts +30 -30
- package/src/templates/scripts/genesys/mcp/search-actors.ts +858 -858
- package/src/templates/scripts/genesys/mcp/search-assets.ts +380 -380
- package/src/templates/scripts/genesys/mcp/utils.ts +281 -281
- package/src/templates/scripts/genesys/misc.ts +42 -42
- package/src/templates/scripts/genesys/mock.ts +6 -6
- package/src/templates/scripts/genesys/place-actors.ts +179 -179
- package/src/templates/scripts/genesys/post-install.ts +30 -30
- package/src/templates/scripts/genesys/prefab.schema.json +84 -84
- package/src/templates/scripts/genesys/remove-engine-comments.ts +134 -134
- package/src/templates/scripts/genesys/run-mcp-inspector.bat +4 -4
- package/src/templates/scripts/genesys/storageProvider.ts +182 -182
- package/src/templates/scripts/genesys/validate-prefabs.ts +138 -138
- package/src/templates/src/index.ts +22 -22
- package/src/templates/src/templates/firstPerson/assets/default.genesys-scene +165 -165
- package/src/templates/src/templates/firstPerson/src/game.ts +39 -39
- package/src/templates/src/templates/firstPerson/src/player.ts +63 -63
- package/src/templates/src/templates/fps/assets/default.genesys-scene +9459 -9459
- package/src/templates/src/templates/fps/src/game.ts +39 -39
- package/src/templates/src/templates/fps/src/player.ts +69 -69
- package/src/templates/src/templates/fps/src/weapon.ts +54 -54
- package/src/templates/src/templates/freeCamera/assets/default.genesys-scene +165 -165
- package/src/templates/src/templates/freeCamera/src/game.ts +39 -39
- package/src/templates/src/templates/freeCamera/src/player.ts +45 -45
- package/src/templates/src/templates/sideScroller/assets/default.genesys-scene +121 -121
- package/src/templates/src/templates/sideScroller/src/const.ts +45 -45
- package/src/templates/src/templates/sideScroller/src/game.ts +122 -122
- package/src/templates/src/templates/sideScroller/src/level-generator.ts +361 -361
- package/src/templates/src/templates/sideScroller/src/player.ts +125 -125
- package/src/templates/src/templates/thirdPerson/assets/default.genesys-scene +165 -165
- package/src/templates/src/templates/thirdPerson/src/game.ts +39 -39
- package/src/templates/src/templates/thirdPerson/src/player.ts +61 -61
- package/src/templates/src/templates/vehicle/assets/default.genesys-scene +225 -225
- package/src/templates/src/templates/vehicle/src/base-vehicle.ts +145 -145
- package/src/templates/src/templates/vehicle/src/game.ts +43 -43
- package/src/templates/src/templates/vehicle/src/mesh-vehicle.ts +191 -191
- package/src/templates/src/templates/vehicle/src/player.ts +109 -109
- package/src/templates/src/templates/vehicle/src/primitive-vehicle.ts +266 -266
- package/src/templates/src/templates/vehicle/src/ui-hints.ts +101 -101
- package/src/templates/src/templates/vr-game/assets/default.genesys-scene +246 -246
- package/src/templates/src/templates/vr-game/src/auto-imports.ts +1 -1
- package/src/templates/src/templates/vr-game/src/game.ts +66 -66
- package/src/templates/src/templates/vr-game/src/sample-vr-actor.ts +26 -26
- package/src/templates/tsconfig.json +34 -34
- 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
|
+
}
|