Implementing Turn-by-Turn Interaction in Shared AR Experience Using Image Targets

Hi everyone,

I’m currently working on a Shared AR project where two players interact with a 3D scene by taking turns. The setup includes two player entities and a dice model, all rendered on an image target. The goal is to implement turn-by-turn interaction: one player taps the dice, their model moves, and then the turn switches to the next player, allowing them to interact.

Each player should own only their respective player entity. For example, player 1 can only move player1’s 3D model and player 2 can only move player2’s 3D model. When it’s one player’s turn, the other player is blocked from interacting with the dice until the first player has completed their move.

We’re using A-Frame, NAF (Networked A-Frame), and 8th Wall for the image tracking, and the interaction happens on an image target. However, we’re facing issues with ownership and ensuring only one player can interact at a time.

Relevant Code Snippets:

app.js (for handling player turns and ownership):

/* globals NAF */
import { lobbyHandlerComponent } from './lobby-handler';
AFRAME.registerComponent('lobby-handler', lobbyHandlerComponent);

let currentPlayerTurn = 1; // Track whose turn it is
let playerOwned = ""; // Track the player's ownership

// Move Player Function
const movePlayer = (player) => {
  // Logic to move the player (e.g., update position)
  player.setAttribute('position', new THREE.Vector3(0.5, 0.5, 0));
};

// Dice click handler
const handleDiceClick = () => {
  const dice = document.querySelector('#dice');
  const player1 = document.querySelector('#player1-entity');
  const player2 = document.querySelector('#player2-entity');

  dice.addEventListener('click', function () {
    // Ensure only the current player can interact
    if ((currentPlayerTurn === 1 && playerOwned === 'player1') ||
        (currentPlayerTurn === 2 && playerOwned === 'player2')) {
      movePlayer(currentPlayerTurn === 1 ? player1 : player2);
      currentPlayerTurn = currentPlayerTurn === 1 ? 2 : 1; // Switch turn
    }
  });
};

body.html (for defining networked entities):

<a-scene networked-scene="adapter: sharedar; connectOnLoad: false">
  <a-assets>
    <!-- Define player models -->
    <template id="player1">
      <a-entity id="player1-entity" gltf-model="#coinModel" networked="template: #player1; networkId: player1"></a-entity>
    </template>
    <template id="player2">
      <a-entity id="player2-entity" gltf-model="#coinModel" networked="template: #player2; networkId: player2"></a-entity>
    </template>
    <template id="dice-template">
      <a-entity id="dice" gltf-model="#diceModel" networked="template: #dice-template; networkId: dice"></a-entity>
    </template>
  </a-assets>
</a-scene>

Issues:

  • Players cannot take turns properly, and we face an ownership issue: β€œThis device does not own the player entity.”
  • How can we manage ownership and ensure only the current player can interact with the dice?

Any help with enabling turn-by-turn functionality would be appreciated!