hytopia 0.1.55 → 0.1.57

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 (109) hide show
  1. package/boilerplate/index.ts +1 -1
  2. package/docs/server.baseentitycontroller.attach.md +53 -0
  3. package/docs/server.baseentitycontroller.despawn.md +53 -0
  4. package/docs/server.baseentitycontroller.detach.md +53 -0
  5. package/docs/server.baseentitycontroller.md +260 -0
  6. package/docs/server.baseentitycontroller.onattach.md +13 -0
  7. package/docs/server.baseentitycontroller.ondespawn.md +13 -0
  8. package/docs/server.baseentitycontroller.ondetach.md +13 -0
  9. package/docs/server.baseentitycontroller.onspawn.md +13 -0
  10. package/docs/server.baseentitycontroller.ontick.md +13 -0
  11. package/docs/server.baseentitycontroller.ontickwithplayerinput.md +13 -0
  12. package/docs/server.baseentitycontroller.spawn.md +53 -0
  13. package/docs/server.baseentitycontroller.tick.md +67 -0
  14. package/docs/{server.basecharactercontroller.tickwithplayerinput.md → server.baseentitycontroller.tickwithplayerinput.md} +20 -4
  15. package/docs/server.entity.controller.md +13 -0
  16. package/docs/server.entity.md +34 -18
  17. package/docs/server.entity.modelanimationsplaybackrate.md +13 -0
  18. package/docs/server.entity.setcontroller.md +53 -0
  19. package/docs/server.entity.setmodelanimationsplaybackrate.md +57 -0
  20. package/docs/server.entityeventpayload.md +9 -0
  21. package/docs/server.entityeventpayload.setmodelanimationsplaybackrate.entity.md +11 -0
  22. package/docs/server.entityeventpayload.setmodelanimationsplaybackrate.md +70 -0
  23. package/docs/server.entityeventpayload.setmodelanimationsplaybackrate.playbackrate.md +11 -0
  24. package/docs/server.entityeventtype.md +14 -0
  25. package/docs/server.entityoptions.controller.md +13 -0
  26. package/docs/server.entityoptions.md +22 -3
  27. package/docs/server.entityoptions.modelanimationsplaybackrate.md +13 -0
  28. package/docs/server.facecallback.md +1 -1
  29. package/docs/server.facecompletecallback.md +1 -1
  30. package/docs/server.faceoptions.md +1 -1
  31. package/docs/server.md +27 -27
  32. package/docs/server.movecallback.md +1 -1
  33. package/docs/server.movecompletecallback.md +1 -1
  34. package/docs/server.moveoptions.md +1 -1
  35. package/docs/server.playerentity.md +1 -1
  36. package/docs/server.playerentitycontroller._constructor_.md +49 -0
  37. package/docs/server.playerentitycontroller.attach.md +53 -0
  38. package/docs/server.playerentitycontroller.canjump.md +13 -0
  39. package/docs/server.playerentitycontroller.canrun.md +13 -0
  40. package/docs/server.playerentitycontroller.canwalk.md +13 -0
  41. package/docs/server.playerentitycontroller.isgrounded.md +13 -0
  42. package/docs/server.playerentitycontroller.isonplatform.md +13 -0
  43. package/docs/server.playerentitycontroller.jumpvelocity.md +13 -0
  44. package/docs/server.playerentitycontroller.md +331 -0
  45. package/docs/server.playerentitycontroller.platform.md +13 -0
  46. package/docs/server.playerentitycontroller.runvelocity.md +13 -0
  47. package/docs/server.playerentitycontroller.spawn.md +53 -0
  48. package/docs/{server.defaultcharactercontroller.tickwithplayerinput.md → server.playerentitycontroller.tickwithplayerinput.md} +20 -4
  49. package/docs/server.playerentitycontroller.walkvelocity.md +13 -0
  50. package/docs/server.playerentitycontrolleroptions.canjump.md +13 -0
  51. package/docs/server.playerentitycontrolleroptions.canrun.md +13 -0
  52. package/docs/server.playerentitycontrolleroptions.canwalk.md +13 -0
  53. package/docs/server.playerentitycontrolleroptions.jumpvelocity.md +13 -0
  54. package/docs/{server.defaultcharactercontrolleroptions.md → server.playerentitycontrolleroptions.md} +10 -10
  55. package/docs/server.playerentitycontrolleroptions.runvelocity.md +13 -0
  56. package/docs/server.playerentitycontrolleroptions.walkvelocity.md +13 -0
  57. package/docs/server.playerui.lockpointer.md +53 -0
  58. package/docs/server.playerui.md +14 -0
  59. package/docs/server.playeruieventpayload.lockpointer.lock.md +11 -0
  60. package/docs/server.playeruieventpayload.lockpointer.md +70 -0
  61. package/docs/server.playeruieventpayload.lockpointer.playerui.md +11 -0
  62. package/docs/server.playeruieventpayload.md +9 -0
  63. package/docs/server.playeruieventtype.md +14 -0
  64. package/docs/{server.simplecharactercontroller.face.md → server.simpleentitycontroller.face.md} +2 -2
  65. package/docs/{server.simplecharactercontroller.md → server.simpleentitycontroller.md} +11 -13
  66. package/docs/{server.simplecharactercontroller.move.md → server.simpleentitycontroller.move.md} +2 -2
  67. package/examples/block-entity/index.ts +7 -7
  68. package/examples/custom-ui/index.ts +1 -1
  69. package/examples/entity-controller/MyEntityController.ts +321 -0
  70. package/examples/entity-controller/README.md +4 -0
  71. package/examples/{character-controller → entity-controller}/index.ts +6 -11
  72. package/examples/{character-controller → entity-controller}/package.json +1 -1
  73. package/examples/payload-game/index.ts +18 -19
  74. package/package.json +1 -1
  75. package/server.api.json +4129 -3498
  76. package/server.d.ts +229 -167
  77. package/server.js +85 -85
  78. package/docs/server.basecharactercontroller._constructor_.md +0 -65
  79. package/docs/server.basecharactercontroller.createcolliders.md +0 -19
  80. package/docs/server.basecharactercontroller.entity.md +0 -13
  81. package/docs/server.basecharactercontroller.md +0 -197
  82. package/docs/server.basecharactercontroller.ontick.md +0 -13
  83. package/docs/server.basecharactercontroller.ontickwithplayerinput.md +0 -13
  84. package/docs/server.basecharactercontroller.tick.md +0 -53
  85. package/docs/server.defaultcharactercontroller._constructor_.md +0 -65
  86. package/docs/server.defaultcharactercontroller.canjump.md +0 -13
  87. package/docs/server.defaultcharactercontroller.canrun.md +0 -13
  88. package/docs/server.defaultcharactercontroller.canwalk.md +0 -13
  89. package/docs/server.defaultcharactercontroller.createcolliders.md +0 -19
  90. package/docs/server.defaultcharactercontroller.isgrounded.md +0 -13
  91. package/docs/server.defaultcharactercontroller.isonplatform.md +0 -13
  92. package/docs/server.defaultcharactercontroller.jumpvelocity.md +0 -13
  93. package/docs/server.defaultcharactercontroller.md +0 -319
  94. package/docs/server.defaultcharactercontroller.platform.md +0 -13
  95. package/docs/server.defaultcharactercontroller.runvelocity.md +0 -13
  96. package/docs/server.defaultcharactercontroller.walkvelocity.md +0 -13
  97. package/docs/server.defaultcharactercontrolleroptions.canjump.md +0 -13
  98. package/docs/server.defaultcharactercontrolleroptions.canrun.md +0 -13
  99. package/docs/server.defaultcharactercontrolleroptions.canwalk.md +0 -13
  100. package/docs/server.defaultcharactercontrolleroptions.jumpvelocity.md +0 -13
  101. package/docs/server.defaultcharactercontrolleroptions.runvelocity.md +0 -13
  102. package/docs/server.defaultcharactercontrolleroptions.walkvelocity.md +0 -13
  103. package/docs/server.entity.charactercontroller.md +0 -13
  104. package/docs/server.entity.createcustomcharactercontroller.md +0 -13
  105. package/docs/server.entity.setcharactercontroller.md +0 -53
  106. package/docs/server.entityoptions.createcustomcharactercontroller.md +0 -13
  107. package/examples/character-controller/MyCharacterController.ts +0 -250
  108. package/examples/character-controller/README.md +0 -4
  109. /package/examples/{character-controller → entity-controller}/assets/map.json +0 -0
@@ -0,0 +1,321 @@
1
+ import {
2
+ Audio,
3
+ BaseEntityController,
4
+ ColliderShape,
5
+ CoefficientCombineRule,
6
+ CollisionGroup,
7
+ Entity,
8
+ PlayerEntity,
9
+ BlockType,
10
+ } from 'hytopia';
11
+
12
+ import type {
13
+ PlayerInput,
14
+ PlayerCameraOrientation,
15
+ } from 'hytopia';
16
+
17
+ /** Options for creating a MyEntityController instance. @public */
18
+ export interface MyEntityControllerOptions {
19
+ /** The upward velocity applied to the entity when it jumps. */
20
+ jumpVelocity?: number;
21
+
22
+ /** The normalized horizontal velocity applied to the entity when it runs. */
23
+ runVelocity?: number;
24
+
25
+ /** The normalized horizontal velocity applied to the entity when it walks. */
26
+ walkVelocity?: number;
27
+
28
+ /** A function allowing custom logic to determine if the entity can jump. */
29
+ canJump?: () => boolean;
30
+
31
+ /** A function allowing custom logic to determine if the entity can walk. */
32
+ canWalk?: () => boolean;
33
+
34
+ /** A function allowing custom logic to determine if the entity can run. */
35
+ canRun?: () => boolean;
36
+ }
37
+
38
+ /**
39
+ * A custom entity controller implementation.
40
+ *
41
+ * @remarks
42
+ * This class extends {@link BaseEntityController}
43
+ * and implements the default movement logic for a
44
+ * entity.
45
+ *
46
+ * @public
47
+ */
48
+ export default class MyEntityController extends BaseEntityController {
49
+ /** The upward velocity applied to the entity when it jumps. */
50
+ public jumpVelocity: number = 10;
51
+
52
+ /** The normalized horizontal velocity applied to the entity when it runs. */
53
+ public runVelocity: number = 8;
54
+
55
+ /** The normalized horizontal velocity applied to the entity when it walks. */
56
+ public walkVelocity: number = 4;
57
+
58
+ /**
59
+ * A function allowing custom logic to determine if the entity can walk.
60
+ * @param myEntityController - The entity controller instance.
61
+ * @returns Whether the entity of the entity controller can walk.
62
+ */
63
+ public canWalk: (myEntityController: MyEntityController) => boolean = () => true;
64
+
65
+ /**
66
+ * A function allowing custom logic to determine if the entity can run.
67
+ * @param myEntityController - The entity controller instance.
68
+ * @returns Whether the entity of the entity controller can run.
69
+ */
70
+ public canRun: (myEntityController: MyEntityController) => boolean = () => true;
71
+
72
+ /**
73
+ * A function allowing custom logic to determine if the entity can jump.
74
+ * @param myEntityController - The entity controller instance.
75
+ * @returns Whether the entity of the entity controller can jump.
76
+ */
77
+ public canJump: (myEntityController: MyEntityController) => boolean = () => true;
78
+
79
+ /** @internal */
80
+ private _stepAudio: Audio | undefined;
81
+
82
+ /** @internal */
83
+ private _groundContactCount: number = 0;
84
+
85
+ /** @internal */
86
+ private _platform: Entity | undefined;
87
+
88
+ /**
89
+ * @param options - Options for the controller.
90
+ */
91
+ public constructor(options: MyEntityControllerOptions = {}) {
92
+ super();
93
+
94
+ this.jumpVelocity = options.jumpVelocity ?? this.jumpVelocity;
95
+ this.runVelocity = options.runVelocity ?? this.runVelocity;
96
+ this.walkVelocity = options.walkVelocity ?? this.walkVelocity;
97
+ this.canWalk = options.canWalk ?? this.canWalk;
98
+ this.canRun = options.canRun ?? this.canRun;
99
+ this.canJump = options.canJump ?? this.canJump;
100
+ }
101
+
102
+ /** Whether the entity is grounded. */
103
+ public get isGrounded(): boolean { return this._groundContactCount > 0; }
104
+
105
+ /** Whether the entity is on a platform, a platform is any entity with a kinematic rigid body. */
106
+ public get isOnPlatform(): boolean { return !!this._platform; }
107
+
108
+ /** The platform the entity is on, if any. */
109
+ public get platform(): Entity | undefined { return this._platform; }
110
+
111
+ /**
112
+ * Called when the controller is attached to an entity.
113
+ * @param entity - The entity to attach the controller to.
114
+ */
115
+ public attach(entity: Entity) {
116
+ this._stepAudio = new Audio({
117
+ uri: 'audio/sfx/step.wav',
118
+ loop: true,
119
+ volume: 0.1,
120
+ attachedToEntity: entity,
121
+ });
122
+
123
+ entity.lockAllRotations(); // prevent physics from applying rotation to the entity, we can still explicitly set it.
124
+ };
125
+
126
+ /**
127
+ * Called when the controlled entity is spawned.
128
+ * In MyEntityController, this function is used to create
129
+ * the colliders for the entity for wall and ground detection.
130
+ * @param entity - The entity that is spawned.
131
+ */
132
+ public spawn(entity: Entity) {
133
+ if (!entity.isSpawned) {
134
+ throw new Error('MyEntityController.createColliders(): Entity is not spawned!');
135
+ }
136
+
137
+ // Ground sensor
138
+ entity.createAndAddChildColliderToSimulation({
139
+ shape: ColliderShape.CYLINDER,
140
+ radius: 0.23,
141
+ halfHeight: 0.125,
142
+ collisionGroups: {
143
+ belongsTo: [ CollisionGroup.ENTITY_SENSOR ],
144
+ collidesWith: [ CollisionGroup.BLOCK, CollisionGroup.ENTITY ],
145
+ },
146
+ isSensor: true,
147
+ relativePosition: { x: 0, y: -0.75, z: 0 },
148
+ tag: 'groundSensor',
149
+ onCollision: (_other: BlockType | Entity, started: boolean) => {
150
+ // Ground contact
151
+ this._groundContactCount += started ? 1 : -1;
152
+
153
+ if (!this._groundContactCount) {
154
+ entity.startModelOneshotAnimations([ 'jump_loop' ]);
155
+ } else {
156
+ entity.stopModelAnimations([ 'jump_loop' ]);
157
+ }
158
+
159
+ // Platform contact
160
+ if (!(_other instanceof Entity) || !_other.isKinematic) return;
161
+
162
+ if (started) {
163
+ this._platform = _other;
164
+ } else if (_other === this._platform && !started) {
165
+ this._platform = undefined;
166
+ }
167
+ },
168
+ });
169
+
170
+
171
+ // Wall collider
172
+ entity.createAndAddChildColliderToSimulation({
173
+ shape: ColliderShape.CAPSULE,
174
+ halfHeight: 0.30,
175
+ radius: 0.37,
176
+ collisionGroups: {
177
+ belongsTo: [ CollisionGroup.ENTITY_SENSOR ],
178
+ collidesWith: [ CollisionGroup.BLOCK ],
179
+ },
180
+ friction: 0,
181
+ frictionCombineRule: CoefficientCombineRule.Min,
182
+ tag: 'wallCollider',
183
+ });
184
+ };
185
+
186
+ /**
187
+ * Ticks the player movement for the entity controller,
188
+ * overriding the default implementation.
189
+ *
190
+ * @param entity - The entity to tick.
191
+ * @param input - The current input state of the player.
192
+ * @param cameraOrientation - The current camera orientation state of the player.
193
+ * @param deltaTimeMs - The delta time in milliseconds since the last tick.
194
+ */
195
+ public tickWithPlayerInput(entity: PlayerEntity, input: PlayerInput, cameraOrientation: PlayerCameraOrientation, deltaTimeMs: number) {
196
+ if (!entity.isSpawned || !entity.world) return;
197
+
198
+ super.tickWithPlayerInput(entity, input, cameraOrientation, deltaTimeMs);
199
+
200
+ const { w, a, s, d, sp, sh, ml } = input;
201
+ const { yaw } = cameraOrientation;
202
+ const currentVelocity = entity.linearVelocity;
203
+ const targetVelocities = { x: 0, y: 0, z: 0 };
204
+ const isRunning = sh;
205
+
206
+ // Temporary, animations
207
+ if (this.isGrounded && (w || a || s || d)) {
208
+ if (isRunning) {
209
+ entity.stopModelAnimations(Array.from(entity.modelLoopedAnimations).filter(v => v !== 'run'));
210
+ entity.startModelLoopedAnimations([ 'run' ]);
211
+ this._stepAudio?.setPlaybackRate(0.83);
212
+ } else {
213
+ entity.stopModelAnimations(Array.from(entity.modelLoopedAnimations).filter(v => v !== 'walk'));
214
+ entity.startModelLoopedAnimations([ 'walk' ]);
215
+ this._stepAudio?.setPlaybackRate(0.5);
216
+ }
217
+
218
+ this._stepAudio?.play(entity.world, !this._stepAudio?.isPlaying);
219
+ } else {
220
+ this._stepAudio?.pause();
221
+ entity.stopModelAnimations(Array.from(entity.modelLoopedAnimations).filter(v => v !== 'idle'));
222
+ entity.startModelLoopedAnimations([ 'idle' ]);
223
+ }
224
+
225
+ if (ml) {
226
+ entity.startModelOneshotAnimations([ 'simple_interact' ]);
227
+
228
+ // break a block
229
+ const ray = entity.world.simulation.raycast(
230
+ entity.position,
231
+ entity.player.camera.facingDirection,
232
+ 10,
233
+ { filterExcludeRigidBody: entity.rawRigidBody },
234
+ );
235
+
236
+ if (ray?.hitBlock) {
237
+ // Remove the block
238
+ entity.world.chunkLattice.setBlock(ray.hitBlock.globalCoordinate, 0);
239
+ }
240
+
241
+ input.ml = false;
242
+ }
243
+
244
+ // Calculate target horizontal velocities (run/walk)
245
+ if ((isRunning && this.canRun(this)) || (!isRunning && this.canWalk(this))) {
246
+ const velocity = isRunning ? this.runVelocity : this.walkVelocity;
247
+
248
+ if (w) {
249
+ targetVelocities.x -= velocity * Math.sin(yaw);
250
+ targetVelocities.z -= velocity * Math.cos(yaw);
251
+ }
252
+
253
+ if (s) {
254
+ targetVelocities.x += velocity * Math.sin(yaw);
255
+ targetVelocities.z += velocity * Math.cos(yaw);
256
+ }
257
+
258
+ if (a) {
259
+ targetVelocities.x -= velocity * Math.cos(yaw);
260
+ targetVelocities.z += velocity * Math.sin(yaw);
261
+ }
262
+
263
+ if (d) {
264
+ targetVelocities.x += velocity * Math.cos(yaw);
265
+ targetVelocities.z -= velocity * Math.sin(yaw);
266
+ }
267
+
268
+ // Normalize for diagonals
269
+ const length = Math.sqrt(targetVelocities.x * targetVelocities.x + targetVelocities.z * targetVelocities.z);
270
+ if (length > velocity) {
271
+ const factor = velocity / length;
272
+ targetVelocities.x *= factor;
273
+ targetVelocities.z *= factor;
274
+ }
275
+ }
276
+
277
+ // Calculate target vertical velocity (jump)
278
+ if (sp && this.canJump(this)) {
279
+ if (this.isGrounded && currentVelocity.y > -0.001 && currentVelocity.y <= 3) {
280
+ targetVelocities.y = this.jumpVelocity;
281
+ }
282
+ }
283
+
284
+ // Apply impulse relative to target velocities, taking platform velocity into account
285
+ const platformVelocity = this._platform ? this._platform.linearVelocity : { x: 0, y: 0, z: 0 };
286
+ const deltaVelocities = {
287
+ x: targetVelocities.x - currentVelocity.x + platformVelocity.x,
288
+ y: targetVelocities.y + platformVelocity.y,
289
+ z: targetVelocities.z - currentVelocity.z + platformVelocity.z,
290
+ };
291
+
292
+ const hasExternalVelocity =
293
+ Math.abs(currentVelocity.x) > this.runVelocity ||
294
+ Math.abs(currentVelocity.y) > this.jumpVelocity ||
295
+ Math.abs(currentVelocity.z) > this.runVelocity;
296
+
297
+ if (!hasExternalVelocity) { // allow external velocities to resolve, otherwise our deltas will cancel them out.
298
+ if (Object.values(deltaVelocities).some(v => v !== 0)) {
299
+ const mass = entity.mass;
300
+
301
+ entity.applyImpulse({ // multiply by mass for the impulse to result in applying the correct target velocity
302
+ x: deltaVelocities.x * mass,
303
+ y: deltaVelocities.y * mass,
304
+ z: deltaVelocities.z * mass,
305
+ });
306
+ }
307
+ }
308
+
309
+ // Apply rotation
310
+ if (yaw !== undefined) {
311
+ const halfYaw = yaw / 2;
312
+
313
+ entity.setRotation({
314
+ x: 0,
315
+ y: Math.fround(Math.sin(halfYaw)),
316
+ z: 0,
317
+ w: Math.fround(Math.cos(halfYaw)),
318
+ });
319
+ }
320
+ }
321
+ }
@@ -0,0 +1,4 @@
1
+ # entity-controller
2
+
3
+ This is a simple demonstration of how you can create your own entity controller. This demonstration
4
+ uses much of the same code as the default entity controller that ships with the SDK.
@@ -3,7 +3,7 @@ import {
3
3
  PlayerEntity,
4
4
  } from 'hytopia';
5
5
 
6
- import MyCharacterController from './MyCharacterController';
6
+ import MyEntityController from './MyEntityController';
7
7
 
8
8
  import worldMap from './assets/map.json';
9
9
 
@@ -11,6 +11,10 @@ startServer(world => {
11
11
  // Uncomment this to visualize physics vertices, will cause noticable lag.
12
12
  // world.simulation.enableDebugRendering(true);
13
13
 
14
+ // Visualize raycasts, like block breaking for our
15
+ // entity controller.
16
+ world.simulation.enableDebugRaycasting(true);
17
+
14
18
  world.loadMap(worldMap);
15
19
 
16
20
  world.onPlayerJoin = player => {
@@ -20,18 +24,9 @@ startServer(world => {
20
24
  modelUri: 'models/player.gltf',
21
25
  modelLoopedAnimations: [ 'idle' ],
22
26
  modelScale: 0.5,
27
+ controller: new MyEntityController(), // attach our entity controller
23
28
  });
24
29
 
25
- // Assign a custom character controller factory to the player entity.
26
- // This must be assigned before spawning the entity.
27
- // createCustomCharacterController if set will be handled internally when
28
- // .spawn() is called.
29
- playerEntity.createCustomCharacterController = () => {
30
- console.log('Creating custom player entity character controller...');
31
-
32
- return new MyCharacterController(playerEntity);
33
- };
34
-
35
30
  playerEntity.spawn(world, { x: 0, y: 10, z: 0 });
36
31
  console.log('Spawned player entity!');
37
32
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "character-controller",
2
+ "name": "entity-controller",
3
3
  "version": "1.0.0",
4
4
  "description": "",
5
5
  "main": "index.js",
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * payload-game is a simple game that encompasses a number of core HYTOPIA SDK systems.
3
3
  * This example utilizes entities, spawning, rigid body, colliders and sensors,
4
- * collision groups, audio, character controller hooks, and more.
4
+ * collision groups, audio, entity controller hooks, and more.
5
5
  *
6
6
  * This example is a quick and dirty implementation of an overwatch style push the payload
7
7
  * in a multiplayer PvE style. Players start the game around the payload and must stay near it
@@ -22,11 +22,11 @@ import {
22
22
  PlayerCameraMode,
23
23
  ColliderShape,
24
24
  CollisionGroup,
25
- DefaultCharacterController,
25
+ PlayerEntityController,
26
26
  Entity,
27
27
  PlayerEntity,
28
28
  RigidBodyType,
29
- SimpleCharacterController,
29
+ SimpleEntityController,
30
30
  Vector3,
31
31
  World,
32
32
  startServer,
@@ -120,7 +120,7 @@ startServer(world => { // Perform our game setup logic in the startServer init c
120
120
  playerEntity.spawn(world, randomSpawnCoordinate);
121
121
 
122
122
  // We need to do some custom logic for player inputs, so let's assign custom onTick handler to the default player controller.
123
- playerEntity.characterController!.onTickWithPlayerInput = onTickWithPlayerInput;
123
+ playerEntity.controller!.onTickWithPlayerInput = onTickWithPlayerInput;
124
124
 
125
125
  // Set custom collision groups for the player entity, this is so we can reference the PLAYER collision group
126
126
  // specifically in enemy collision sensors.
@@ -293,7 +293,7 @@ function spawnPayloadEntity(world: World) {
293
293
  }
294
294
 
295
295
  payloadEntity = new Entity({
296
- createCustomCharacterController: (entity: Entity) => new SimpleCharacterController(entity),
296
+ controller: new SimpleEntityController(),
297
297
  name: 'Payload',
298
298
  modelUri: 'models/payload.gltf',
299
299
  modelScale: 0.7,
@@ -350,7 +350,7 @@ function spawnSpider(world: World, coordinate: Vector3Like) {
350
350
  const targetPlayers = new Set<PlayerEntity>();
351
351
 
352
352
  const spider = new Entity({
353
- createCustomCharacterController: (entity: Entity) => new SimpleCharacterController(entity),
353
+ controller: new SimpleEntityController(),
354
354
  name: 'Spider',
355
355
  modelUri: 'models/spider.gltf',
356
356
  modelLoopedAnimations: [ 'walk' ],
@@ -444,16 +444,16 @@ function onTickPathfindPayload(entity: Entity) { // Movement logic for the paylo
444
444
  return console.warn('Payload destination reached!! Game won!!');
445
445
  }
446
446
 
447
- if (!(entity.characterController instanceof SimpleCharacterController)) { // type guard
448
- return console.warn('Payload entity does not have a SimpleCharacterController!');
447
+ if (!(entity.controller instanceof SimpleEntityController)) { // type guard
448
+ return console.warn('Payload entity does not have a SimpleEntityController!');
449
449
  }
450
450
 
451
- entity.characterController.move(targetWaypointCoordinate, speed, {
451
+ entity.controller.move(targetWaypointCoordinate, speed, {
452
452
  moveCompleteCallback: () => targetWaypointCoordinateIndex++,
453
453
  moveIgnoreAxes: { y: true },
454
454
  });
455
455
 
456
- entity.characterController.face(targetWaypointCoordinate, speed / 2);
456
+ entity.controller.face(targetWaypointCoordinate, speed / 2);
457
457
  }
458
458
 
459
459
  function onTickPathfindEnemy(entity: Entity, targetPlayers: Set<PlayerEntity>, speed: number, _tickDeltaMs: number) {
@@ -483,24 +483,23 @@ function onTickPathfindEnemy(entity: Entity, targetPlayers: Set<PlayerEntity>, s
483
483
  }
484
484
 
485
485
  // Handle Movement
486
- if (!(entity.characterController instanceof SimpleCharacterController)) {
487
- return console.warn('Enemy entity does not have a SimpleCharacterController!');
486
+ if (!(entity.controller instanceof SimpleEntityController)) {
487
+ return console.warn('Enemy entity does not have a SimpleEntityController!');
488
488
  }
489
489
 
490
490
  const targetPosition = enemyPathfindingTargets[entityId];
491
- entity.characterController.move(targetPosition, speed, { moveIgnoreAxes: { y: true } });
492
- entity.characterController.face(targetPosition, speed / 2);
491
+ entity.controller.move(targetPosition, speed, { moveIgnoreAxes: { y: true } });
492
+ entity.controller.face(targetPosition, speed / 2);
493
493
  }
494
494
 
495
495
  enemyPathfindAccumulators[entityId]++;
496
496
  }
497
497
 
498
- function onTickWithPlayerInput(this: DefaultCharacterController, input: PlayerInput, cameraOrientation: PlayerCameraOrientation, _deltaTimeMs: number) {
499
- if (!this.entity.world) return;
498
+ function onTickWithPlayerInput(this: PlayerEntityController, entity: PlayerEntity, input: PlayerInput, cameraOrientation: PlayerCameraOrientation, _deltaTimeMs: number) {
499
+ if (!entity.world) return;
500
500
 
501
501
  if (input.ml) {
502
- const world = this.entity.world;
503
- const entity = this.entity;
502
+ const world = entity.world;
504
503
  const direction = Vector3.fromVector3Like(entity.directionFromRotation);
505
504
 
506
505
  direction.y = Math.sin(cameraOrientation.pitch);
@@ -513,7 +512,7 @@ function onTickWithPlayerInput(this: DefaultCharacterController, input: PlayerIn
513
512
  // Normalize the direction vector to unit length
514
513
  direction.normalize();
515
514
 
516
- this.entity.startModelOneshotAnimations([ 'shoot' ]);
515
+ entity.startModelOneshotAnimations([ 'shoot' ]);
517
516
 
518
517
  // Adjust bullet origin roughly for camera offset so crosshair is accurate
519
518
  const bulletOrigin = entity.position;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hytopia",
3
- "version": "0.1.55",
3
+ "version": "0.1.57",
4
4
  "description": "The HYTOPIA SDK makes it easy for developers to create massively multiplayer games using JavaScript or TypeScript.",
5
5
  "main": "server.js",
6
6
  "bin": {