Adding a Physics Body to a Mesh when Using Colyseus

I’m using a colyseus server which receives and send player’s positions to each client. It works great when using a simple mesh to represent to other players (You can’t see it on the GIF, but it’s actually super responsive! :slight_smile: ) :

chrome-capture-2024-7-8

import * as BABYLON from '@babylonjs/core';
import * as Colyseus from 'colyseus.js';

let scene: BABYLON.Scene;
const otherPlayers: Map<string, BABYLON.Mesh> = new Map();

export function initializeOtherPlayerUpdates(colyseusRoom: Colyseus.Room, gameScene: BABYLON.Scene) {
  scene = gameScene;

  colyseusRoom.onMessage('playerPosition', (data: { sessionId: string, x: number, y: number, z: number }) => {
    if (!otherPlayers.has(data.sessionId)) {
      // Create a new mesh for the new player
      const capsule = BABYLON.MeshBuilder.CreateCapsule('otherPlayer', { radius: 1, height: 2.5 }, scene);
      capsule.position.set(data.x, data.y, data.z);
      otherPlayers.set(data.sessionId, capsule);
    } else {
      // Update the position of the existing player mesh
      const playerMesh = otherPlayers.get(data.sessionId);
      if (playerMesh) {
        playerMesh.position.set(data.x, data.y, data.z);
      }
    }
  });
}



I’m triyng to figure out how to add a Physics Body like a Kinematic Body in Ammo js, which will collide with the players but not be effected by collisions itself. For this I tried using an ANIMATED Motion Type like this:

export function initializeOtherPlayerUpdates(colyseusRoom: Colyseus.Room, gameScene: BABYLON.Scene) {
    scene = gameScene;

    colyseusRoom.onMessage('playerPosition', (data: { sessionId: string, x: number, y: number, z: number }) => {
        if (!otherPlayers.has(data.sessionId)) {
            // Create a new mesh for the new player
            const capsule = BABYLON.MeshBuilder.CreateCapsule('otherPlayer', { radius: 1, height: 2.5 }, scene);
            capsule.position.set(data.x, data.y, data.z);

            // Define physics properties and attach them to the mesh
            const cylinderShape = new PhysicsShapeCylinder(
                new BABYLON.Vector3(0, -2, 0),    // starting point of the cylinder segment
                new BABYLON.Vector3(0, 1.5, 0),   // ending point of the cylinder segment
                1,                                // radius of the cylinder,
                scene
            );

            const cylinderBody = new PhysicsBody(capsule, PhysicsMotionType.ANIMATED, false, scene);
            cylinderBody.shape = cylinderShape; // Attach the cylinder shape to the physics body
            cylinderShape.material = { friction: 0.2, restitution: 0 };

            // Set collision filtering for the player
            cylinderShape.filterMembershipMask = 0x0001; // Member of category 1
            cylinderShape.filterCollideMask = 0xFFFD;    // Collides with everything except category 2

            // Set the mass properties
            cylinderBody.setMassProperties({
                mass: 18,
                inertia: new BABYLON.Vector3(0, 0, 0), // Prevent rotation
            });

            otherPlayers.set(data.sessionId, { mesh: capsule, body: cylinderBody });
        } else {
            // Update the position of the existing player mesh
            const player = otherPlayers.get(data.sessionId);
            if (player) {
                player.mesh.position.set(data.x, data.y, data.z);

                // Ensure the physics body follows the mesh position
                const body = player.body;
                if (body) {
                    body.transformNode.position.set(data.x, data.y, data.z);
                }
            }
        }
    });
}

But now the player is frozen in the air at the initial position and does not update.

Any suggestions on how to add the physics body that updated with the mesh’s position received from the server?

Thanks for the help :slight_smile:

Physics body is part of Physics V2, with Havok. Ammo.js is legacy Physics V1. V1 and V2 are incompatible.

Sorry for not explaining properly.

I’m using Havok in this project. I’m trying to create something like a Kinematic body I have done using colyseus and Ammo js in an other project. I tried using A Physics Body and setting the motion type to ANIMATED but it doesn’t seem to work.

I think it’s because of this:
https://doc.babylonjs.com/features/featuresDeepDive/physics/prestep

2 Likes

Yep , that was it! :raised_hands:

Just needed to set:

cylinderBody.disablePreStep = false;

Thank you for the help as always, so quick :smiley:

1 Like