some progress
This commit is contained in:
parent
c4c25f554c
commit
3084fefc4f
|
@ -22,8 +22,6 @@ export class GameplayComponent extends EngineComponent {
|
|||
public world!: World;
|
||||
public cleanUpEvents?: () => void;
|
||||
|
||||
public characters: Humanoid[] = [];
|
||||
|
||||
public controls!: ThirdPersonCamera;
|
||||
public character!: Humanoid;
|
||||
public movementSpeed = 16;
|
||||
|
@ -35,6 +33,9 @@ export class GameplayComponent extends EngineComponent {
|
|||
};
|
||||
public jump = false;
|
||||
|
||||
private prevVelocity = new Vector3();
|
||||
private prevJump = false;
|
||||
|
||||
private move = new Vector3();
|
||||
private look = new Vector3();
|
||||
private server = new GameSocket(this.events);
|
||||
|
@ -72,18 +73,30 @@ export class GameplayComponent extends EngineComponent {
|
|||
this.character?.localToWorld(this.look);
|
||||
|
||||
this.character?.setVelocity(this.move);
|
||||
|
||||
const look = this.move.clone().normalize();
|
||||
if (this.move.length()) {
|
||||
this.character?.setLook(look);
|
||||
}
|
||||
this.events.emit('sendPlayer', {
|
||||
velocity: this.move,
|
||||
lookAt: look,
|
||||
});
|
||||
|
||||
let jump = false;
|
||||
if (this.jump) {
|
||||
jump = true;
|
||||
this.jump = false;
|
||||
this.character?.jump();
|
||||
}
|
||||
|
||||
if (!this.move.equals(this.prevVelocity) || jump !== this.prevJump) {
|
||||
this.events.emit('sendPlayer', {
|
||||
playerId: this.uuid,
|
||||
velocity: this.move,
|
||||
lookAt: look,
|
||||
jump,
|
||||
});
|
||||
}
|
||||
|
||||
this.prevVelocity.copy(this.move);
|
||||
this.prevJump = jump;
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
|
@ -94,12 +107,16 @@ export class GameplayComponent extends EngineComponent {
|
|||
name: string,
|
||||
pos?: Vector3,
|
||||
rot?: Quaternion,
|
||||
uuid?: string
|
||||
uuid?: string,
|
||||
objectUUID?: string
|
||||
) {
|
||||
const char = await instanceCharacterObject(name, pos, uuid);
|
||||
const char = await instanceCharacterObject(name, pos);
|
||||
const ctrl = getCharacterController(char);
|
||||
|
||||
if (uuid) ctrl.uuid = uuid;
|
||||
if (objectUUID) char.uuid = objectUUID;
|
||||
|
||||
this.world.add(char);
|
||||
this.characters.push(ctrl);
|
||||
|
||||
if (rot) char.quaternion.copy(rot);
|
||||
|
||||
|
@ -158,7 +175,8 @@ export class GameplayComponent extends EngineComponent {
|
|||
event.playerName,
|
||||
event.position,
|
||||
event.rotation,
|
||||
event.playerId
|
||||
event.playerId,
|
||||
event.objectUUID
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -181,11 +181,21 @@ export class LevelComponent extends EngineComponent {
|
|||
Object.assign(this.environment, environmentDefaults);
|
||||
};
|
||||
|
||||
const queueFreeEvent = (obj: Object3D | string) => {
|
||||
const object =
|
||||
typeof obj === 'string'
|
||||
? this.world.getObjectByProperty('uuid', obj)
|
||||
: obj;
|
||||
if (!object) return;
|
||||
this.events.emit('remove', { object });
|
||||
};
|
||||
|
||||
this.events.addListener('change', changeEvent);
|
||||
this.events.addListener('remove', removeEvent);
|
||||
this.events.addListener('reparent', reparentEvent);
|
||||
this.events.addListener('instance', instanceEvent);
|
||||
this.events.addListener('reset', resetEvent);
|
||||
this.events.addListener('queueFree', queueFreeEvent);
|
||||
|
||||
return () => {
|
||||
this.events.removeEventListener('change', changeEvent);
|
||||
|
@ -193,6 +203,7 @@ export class LevelComponent extends EngineComponent {
|
|||
this.events.removeEventListener('reparent', reparentEvent);
|
||||
this.events.removeEventListener('instance', instanceEvent);
|
||||
this.events.removeEventListener('reset', resetEvent);
|
||||
this.events.removeEventListener('queueFree', queueFreeEvent);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Humanoid } from '../gameobjects/humanoid.object';
|
|||
import { PhysicsObject } from '../gameobjects/physics.object';
|
||||
import { GameObject } from '../types/game-object';
|
||||
import type Rapier from '@dimforge/rapier3d';
|
||||
import { ServerTransformEvent } from '..';
|
||||
import { PlayerEvent, ServerTransformEvent } from '../types/events';
|
||||
|
||||
export class PhysicsWorldComponent extends EngineComponent {
|
||||
public name = PhysicsWorldComponent.name;
|
||||
|
@ -17,6 +17,7 @@ export class PhysicsWorldComponent extends EngineComponent {
|
|||
private cleanUpEvents?: Function;
|
||||
private sceneInitialized = false;
|
||||
private trackedObjects: PhysicsTicking[] = [];
|
||||
private physicsTick?: ReturnType<typeof setInterval>;
|
||||
|
||||
initialize(): void {
|
||||
this.world = this.renderer.scene.getObjectByName('World') as World;
|
||||
|
@ -30,6 +31,7 @@ export class PhysicsWorldComponent extends EngineComponent {
|
|||
}
|
||||
|
||||
dispose(): void {
|
||||
clearInterval(this.physicsTick);
|
||||
this.cleanUpEvents?.call(this);
|
||||
this.physicsWorld.removeCharacterController(this.characterPhysics);
|
||||
for (const object of this.trackedObjects) object.dispose();
|
||||
|
@ -71,16 +73,28 @@ export class PhysicsWorldComponent extends EngineComponent {
|
|||
object.rigidBody?.setAngvel(event.angularVelocity, false);
|
||||
};
|
||||
|
||||
const characterMoveEvent = (event: PlayerEvent) => {
|
||||
const object = this.trackedObjects.find(
|
||||
(obj) => event.playerId === obj.uuid
|
||||
) as Humanoid;
|
||||
if (!object) return;
|
||||
object.setVelocity(event.velocity);
|
||||
object.setLook(event.lookAt);
|
||||
if (event.jump) object.jump();
|
||||
};
|
||||
|
||||
this.events.addListener('loadComplete', worldLoadEvent);
|
||||
this.events.addListener('sceneJoin', sceneJoinEvent);
|
||||
this.events.addListener('sceneLeave', sceneLeaveEvent);
|
||||
this.events.addListener('serverTransform', serverTransformEvent);
|
||||
this.events.addListener('moveCharacter', characterMoveEvent);
|
||||
|
||||
return () => {
|
||||
this.events.removeEventListener('loadComplete', worldLoadEvent);
|
||||
this.events.removeEventListener('sceneJoin', sceneJoinEvent);
|
||||
this.events.removeEventListener('sceneLeave', sceneLeaveEvent);
|
||||
this.events.removeEventListener('serverTransform', serverTransformEvent);
|
||||
this.events.removeEventListener('moveCharacter', characterMoveEvent);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -124,11 +138,15 @@ export class PhysicsWorldComponent extends EngineComponent {
|
|||
root.traverse((object) => {
|
||||
if (trackedObjects.some((item) => item.uuid === object.uuid)) {
|
||||
physicsLeaveUUIDs.push(object.uuid);
|
||||
|
||||
if ((object as PhysicsObject).dispose) {
|
||||
(object as PhysicsObject).dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.trackedObjects = this.trackedObjects.filter((object) =>
|
||||
physicsLeaveUUIDs.includes(object.uuid)
|
||||
this.trackedObjects = this.trackedObjects.filter(
|
||||
(object) => !physicsLeaveUUIDs.includes(object.uuid)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ export class GameSocket implements Disposable {
|
|||
}
|
||||
|
||||
dispose(): void {
|
||||
this.cleanUpEvents?.();
|
||||
this.disconnect();
|
||||
}
|
||||
|
||||
private onOpen() {
|
||||
|
@ -71,6 +71,11 @@ export class GameSocket implements Disposable {
|
|||
});
|
||||
break;
|
||||
}
|
||||
case PacketType.STREAM_DESTROY: {
|
||||
const objectUUID = incoming.read(String)!;
|
||||
this.events.emit('queueFree', objectUUID);
|
||||
break;
|
||||
}
|
||||
case PacketType.STREAM_TRANSFORM: {
|
||||
const objectUUID = incoming.read(String)!;
|
||||
const objectPos = incoming.read<Vector3>('vec3')!;
|
||||
|
@ -109,12 +114,28 @@ export class GameSocket implements Disposable {
|
|||
const playerName = incoming.read(String)!;
|
||||
const position = incoming.read<Vector3>('vec3')!;
|
||||
const rotation = incoming.read<Quaternion>('quat')!;
|
||||
const objectUUID = incoming.read(String)!;
|
||||
this.events.emit('spawnCharacter', {
|
||||
playerId,
|
||||
playerName,
|
||||
position,
|
||||
rotation,
|
||||
objectUUID,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case PacketType.PLAYER_MOVEMENT: {
|
||||
const playerUUID = incoming.read(String)!;
|
||||
const playerVelocity = incoming.read<Vector3>('vec3')!;
|
||||
const playerLookAt = incoming.read<Vector3>('vec3')!;
|
||||
const playerJump = incoming.read<boolean>('bool')!;
|
||||
this.events.emit('moveCharacter', {
|
||||
playerId: playerUUID,
|
||||
velocity: playerVelocity,
|
||||
lookAt: playerLookAt,
|
||||
jump: playerJump,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,15 +162,23 @@ export class GameSocket implements Disposable {
|
|||
if (this.ws?.readyState !== WebSocket.OPEN) return;
|
||||
this.ws.send(
|
||||
new Packet(PacketType.PLAYER_MOVEMENT)
|
||||
.write(event.playerId, String)
|
||||
.write(event.velocity, 'vec3')
|
||||
.write(event.lookAt, 'vec3')
|
||||
.write(event.jump, 'bool')
|
||||
.toBuffer()
|
||||
);
|
||||
};
|
||||
|
||||
const onBeforeUnload = () => {
|
||||
this.disconnect();
|
||||
};
|
||||
|
||||
this.events.on('sendPlayer', sendPlayerEvent);
|
||||
window.addEventListener('beforeunload', onBeforeUnload);
|
||||
return () => {
|
||||
this.events.removeEventListener('sendPlayer', sendPlayerEvent);
|
||||
window.removeEventListener('beforeunload', onBeforeUnload);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,8 +78,10 @@ export interface ServerTransformEvent {
|
|||
}
|
||||
|
||||
export interface PlayerEvent {
|
||||
playerId?: string;
|
||||
velocity: Vector3;
|
||||
lookAt: Vector3;
|
||||
jump: boolean;
|
||||
}
|
||||
|
||||
export interface SpawnEvent {
|
||||
|
@ -87,6 +89,7 @@ export interface SpawnEvent {
|
|||
playerName: string;
|
||||
position: Vector3;
|
||||
rotation: Quaternion;
|
||||
objectUUID: string;
|
||||
}
|
||||
|
||||
export type EngineEvents = {
|
||||
|
@ -102,7 +105,7 @@ export type EngineEvents = {
|
|||
instance: (event: InstanceEvent) => void;
|
||||
sceneJoin: (event: Object3D) => void;
|
||||
sceneLeave: (event: Object3D) => void;
|
||||
queueFree: (event: Object3D) => void;
|
||||
queueFree: (event: Object3D | string) => void;
|
||||
loadComplete: () => void;
|
||||
physicsComplete: () => void;
|
||||
initialized: () => void;
|
||||
|
@ -110,6 +113,7 @@ export type EngineEvents = {
|
|||
|
||||
spawnCharacter: (event: SpawnEvent) => void;
|
||||
sendPlayer: (event: PlayerEvent) => void;
|
||||
moveCharacter: (event: PlayerEvent) => void;
|
||||
serverConnect: () => void;
|
||||
serverTransform: (obj: ServerTransformEvent) => void;
|
||||
serverDisconnect: () => void;
|
||||
|
|
|
@ -38,8 +38,7 @@ export const loadBaseCharacter = async () => {
|
|||
|
||||
export const instanceCharacterObject = async (
|
||||
name: string,
|
||||
pos = new Vector3(0, 1, 0),
|
||||
uuid?: string
|
||||
pos = new Vector3(0, 1, 0)
|
||||
) => {
|
||||
const base = await loadBaseCharacter();
|
||||
|
||||
|
@ -83,7 +82,6 @@ export const instanceCharacterObject = async (
|
|||
const controller = new Humanoid();
|
||||
controller.position.set(0, 4.75, 0);
|
||||
controller.archivable = false;
|
||||
if (uuid) controller.uuid = uuid;
|
||||
baseObject.add(controller);
|
||||
baseObject.position.copy(pos);
|
||||
|
||||
|
|
Loading…
Reference in New Issue