aframevr / aframevr/aframe

Consider stricter lifecycle guarantees

Open
#3,556 15 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
17.6k
Forks
4.4k
PR merge metrics
No merged PRs in 30d

Description

Got bit recently with an unexpected issue writing a component, thought I'd write it up for ideas...

The nav-mesh component needs the mesh from the entity it's attached to, and needs to account for transformations on its parents. I'd imagined this would be simple enough:

AFRAME.registerComponent('nav-mesh', {
  init: function () {
    this.loadNavMesh();
    this.el.addEventListener('object3dset', () => this.loadNavMesh());
  },

  loadNavMesh: function () {
    const navMesh = this.el.getObject3D('mesh');

    if (!navMesh) return;

    const navMeshGeometry = navMesh.geometry.isBufferGeometry
      ? new THREE.Geometry().fromBufferGeometry(navMesh.geometry)
      : navMesh.geometry.clone();

    scene.updateMatrixWorld();
    navMeshGeometry.applyMatrix(navMesh.matrixWorld);
    this.system.setNavMeshGeometry(navMeshGeometry);
  }
});

Unfortunately this fails — when init runs, the entity's parents do not have their position/rotation/scale applied yet, so scene.updateMatrixWorld() does nothing, and the transformation isn't applied to the Geometry.

Next I assumed update() would be a safe place to put the loadNavMesh() call, but it too runs before parents are initialized. I don't want this code to run on play (it shouldn't reload when the scene pauses) so instead I ended up with:

tick: function (t) {
  if (t === 0) this.loadNavMesh();
}

Anyway, all of this was a little more complicated than I expected, and harder than component lifecycles in e.g. Angular. Saw this issue (or similar) called out as a pain point compared to Unity recently, too:

Have to wrestle with asynchronicity issues that you generally don’t run into with Unity (e.g. why is this model loading BEFORE something else it is dependent on …)

Anyway, I don't have a concrete proposal at the moment but wanted to think about tightening up component lifecycles in a future version and documenting clearly what component authors should expect.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the init, update, play, and tick lifecycle entry points described in the issue, then reproduce the nav-mesh timing case with the shown object3dset listener and THREE geometry path. Done should be a concrete lifecycle guarantee or clearly documented expectation for component authors, supported by an agreed proposal.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, three.js
Domain
frontend, web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.