\n","publisher":{"@type":"Organization","name":"MML","url":"https://mml.io"}}MML - Metaverse Markup Language

MMLCollisionMoveEvent extendsRemoteEvent

Received when a user moves the collision point they are colliding at on an element.

<m-label y="5" z="-3" width="10" height="5" color="red" font-size="150">
</m-label>

<m-cube id="my-cube" y="0.1" z="5" width="4" depth="2" height="0.3" collision-interval="100"></m-cube>

<script>
  const labelElement = document.querySelector("m-label")
  const collidingCube = document.querySelector("#my-cube");

  collidingCube.addEventListener("collisionmove", ({ detail }) => {
    const text = `User at
x: ${detail.position.x.toString().substring(0, 6)},
y: ${detail.position.y.toString().substring(0, 6)},
z: ${detail.position.z.toString().substring(0, 6)}`

    labelElement.setAttribute("content", text)
  })
</script>

detailisReadonly

detail: { position: Position connectionId: number }

Type declaration

  • position:  
  • { x: number y: number z: number }

The position of the collision relative to the element's origin

  • connectionId:  
  • number

The unique numeric id of the connection that sent the event.

typeisReadonly

The **

type

** read-only property of the Event interface returns a string containing the event's type.

MDN Reference

Literal: collisionmove

Examples

Move check

<!--Basic example of element collision-->
<m-cube
  id="collision-ground"
  y="0.2"
  height="0.1"
  width="3"
  depth="3"
  color="green"
  collision-interval="200"
></m-cube>

<script>
  const collisionGround = document.getElementById("collision-ground");

  function getShortenedPosition(position) {
    return {
      x: position.x.toString().substring(0, 6),
      y: position.y.toString().substring(0, 6),
      z: position.z.toString().substring(0, 6),
    };
  }

  let lastKnownPosition = { x: 0, y: 0, z: 0 };

  collisionGround.addEventListener("collisionmove", ({ detail }) => {
    // This is because of javascript floating point precision
    const shortenedPosition = getShortenedPosition(detail.position);

    // This is to prevent the label from updating every frame if the position is the same
    if (JSON.stringify(lastKnownPosition) === JSON.stringify(shortenedPosition)) return;

    lastKnownPosition = shortenedPosition;

    const colors = ["black", "blue", "green", "white", "red", "purple"];

    let selectedColor = Math.floor(Math.random() * colors.length);

    // We don't want the color to be the same as the ground
    while (colors[selectedColor] === collisionGround.getAttribute("color")) {
      selectedColor = Math.floor(Math.random() * colors.length);
    }

    collisionGround.setAttribute("color", colors[selectedColor]);
  });
</script>

Moving object

<!-- Define a larger cube where the user cubes will appear -->
<m-cube id="users-panel" height="6" width="12" depth="0.1" y="4" z="-2">
  <!-- This group will contain all the users cubes -->
  <m-group rx="90" id="user-presence-holder"></m-group>
</m-cube>

<!-- Define a platform that detects collisions -->
<m-cube
  id="platform"
  y="0.05"
  height="0.1"
  width="6"
  depth="3"
  color="green"
  collision-interval="100"
></m-cube>

<script>
  const platform = document.getElementById("platform");
  const userPresenceHolder = document.getElementById("user-presence-holder");

  // A map that will hold the user's connectionId and
  // their associated cube on the users panel.
  let standingUsers = new Map();

  // A function to either fetch the existing cube representation
  // for a user or create one.
  function getOrCreateUser(connectionId, position) {
    const user = standingUsers.get(connectionId);
    if (user) {
      user.position = position;
      return user;
    }

    // Create a new cube to represent the user.
    const userCube = document.createElement("m-cube");
    userCube.setAttribute("collide", false);
    userCube.setAttribute("width", 0.25);
    userCube.setAttribute("height", 0.25);
    userCube.setAttribute("depth", 0.25);
    userCube.setAttribute("color", `#${Math.floor(Math.random() * 0xffffff).toString(16)}`);
    userPresenceHolder.append(userCube);

    const newUser = {
      cube: userCube,
      position,
    };
    standingUsers.set(connectionId, newUser);
    return newUser;
  }

  // Function to set the cube's position based on the user's position
  // on the platform.
  function setCubePosition(connectionId, position) {
    const user = getOrCreateUser(connectionId, position);
    user.cube.setAttribute("x", position.x * 2);
    user.cube.setAttribute("y", 0.2);
    user.cube.setAttribute("z", position.z * 2);
  }

  // Remove user representation when they disconnect or stop colliding.
  function clearUser(connectionId) {
    const user = standingUsers.get(connectionId);
    if (!user) return;
    user.cube.remove();
    standingUsers.delete(connectionId);
  }

  // When a user disconnects, their representation is cleared.
  window.addEventListener("disconnected", (event) => {
    const { connectionId } = event.detail;
    clearUser(connectionId);
  });

  // When a collision starts, set the position of the cube representation.
  function handleCollisionstart(e) {
    const { connectionId, position } = event.detail;
    setCubePosition(connectionId, position);
  }

  // Update cube position when the user moves while colliding.
  function handleCollisionmove(e) {
    const { connectionId, position } = event.detail;
    setCubePosition(connectionId, position);
  }

  // Clear user representation when collision ends.
  function handleCollisionend(e) {
    const { connectionId } = event.detail;
    clearUser(connectionId);
  }

  // Add the necessary event listeners to the platform.
  platform.addEventListener("collisionstart", handleCollisionstart);
  platform.addEventListener("collisionmove", handleCollisionmove);
  platform.addEventListener("collisionend", handleCollisionend);
</script>