Error that occurs when setting ParticleEmitter in Niantic studio

Hi I am creating an AR in Niantic Studio.
When an entity does ecs.physics.COLLISION_END_EVENT, I am setting the ParticleEmitter.
but I get an error (although it looks and works fine).
What causes this error? Could you help me?

I have set ParticleEmitter as follows:

ecs.ParticleEmitter.set(world, eid, {
    stopped: false,
    emitterLife: 1.2,
    particlesPerShot: 1,
    emitDelay: 0,
    minimumLifespan: 0.01,
    maximumLifespan: 0.2,
    mass: 1,
    gravity: 0.01,
    scale: 0.0005,
    spawnAreaType: 'box',
    spawnAreaWidth: 0.1,
    spawnAreaHeight: 0.1,
    spawnAreaDepth: 0.1,
    resourceType: 'model',
    resourceUrl: './assets/particle.glb',
    blendingMode: 'normal',
    animateColor: true,
    colorStart: '#E7C94D',
    colorEnd: '#FFFFFF',
    randomDrift: true,
    randomDriftRange: 0.1,
    collisions: false,
  })

Errors are as follows.

▼ Unhandled promise rejection: SyntaxError: Unexpected token '<', "<?xml vers"... is not valid JSON
    at GLTFLoader.parse runtime.js
    at (anonymous) runtime.js
    at GLTFLoader.parseAsync runtime.js
    at (anonymous) runtime.js
SyntaxError: Unexpected token '<', "<?xml vers"... is not valid JSON

I checked particle.glb with the gltf validator and it seems to be error free.
https://github.khronos.org/glTF-Validator/

{
    "uri": "particle.glb",
    "mimeType": "model/gltf-binary",
    "validatorVersion": "2.0.0-dev.3.10",
    "validatedAt": "2025-01-20T06:46:32.049Z",
    "issues": {
        "numErrors": 0,
        "numWarnings": 0,
        "numInfos": 0,
        "numHints": 0,
        "messages": [],
        "truncated": false
    },
    "info": {
        "version": "2.0",
        "generator": "Khronos glTF Blender I/O v4.1.62",
        "resources": [
            {
                "pointer": "/buffers/0",
                "mimeType": "application/gltf-buffer",
                "storage": "glb",
                "byteLength": 168
            }
        ],
        "animationCount": 0,
        "materialCount": 0,
        "hasMorphTargets": false,
        "hasSkins": false,
        "hasTextures": false,
        "hasDefaultScene": true,
        "drawCallCount": 1,
        "totalVertexCount": 8,
        "totalTriangleCount": 12,
        "maxUVs": 0,
        "maxInfluences": 0,
        "maxAttributes": 1
    }
}

Below is the full text of the relevant code.

// This is a component file. You can use this file to define a custom component for your project.
// This component will appear as a custom component in the editor.

import * as ecs from '@8thwall/ecs'  // This is how you access the ecs library.

let customUi
let originalBox
let handleCollision

const {BoxGeometry, Material, Position, Quaternion, Scale, Shadow, ScaleAnimation, Audio} = ecs

const block = ecs.registerComponent({
  name: 'block',
  schema: {
    customUi: ecs.eid,
    originalBox: ecs.eid,
  },
  schemaDefaults: {
  },
  data: {
    // Add data that cannot be configured outside of the component.
  },
  add: (world, component) => {
    const {eid} = component
    customUi = component.schema.customUi
    originalBox = component.schema.originalBox

    const componentsForRemove = [
      Position, Quaternion, Scale, Shadow, BoxGeometry, Material,
      ecs.CustomPropertyAnimation, ecs.CustomVec3Animation, ecs.FollowAnimation,
      ecs.LookAtAnimation, ecs.GltfModel, ecs.Collider, ecs.ParticleEmitter, ecs.Audio,
    ]

    const removeComponents = (world_, targetEid) => {
      componentsForRemove.forEach((component_) => {
        if (targetEid !== originalBox) {
          if (component_.has(world_, targetEid)) {
            component_.remove(world_, targetEid)
          }
        }
      })
    }

    handleCollision = (e) => {
      ecs.Hidden.set(world, eid, {})

      ecs.ParticleEmitter.set(world, eid, {
        stopped: false,
        emitterLife: 1.2,
        particlesPerShot: 1,
        emitDelay: 0,
        minimumLifespan: 0.01,
        maximumLifespan: 0.2,
        mass: 1,
        gravity: 0.01,
        scale: 0.0005,
        spawnAreaType: 'box',
        spawnAreaWidth: 0.1,
        spawnAreaHeight: 0.1,
        spawnAreaDepth: 0.1,
        resourceType: 'model',
        resourceUrl: './assets/particle.glb',
        blendingMode: 'normal',
        animateColor: true,
        colorStart: '#E7C94D',
        colorEnd: '#FFFFFF',
        randomDrift: true,
        randomDriftRange: 0.1,
        collisions: false,
      })

      // if (ecs.Audio.has(world, eid)) {
      //   const audio = ecs.Audio.cursor(world, eid)
      //   audio.paused = false
      // }

      // ecs.Audio.mutate(world, eid, (cursor) => {
      //   cursor.paused = false
      // })

      if (ecs.Collider.has(world, eid)) {
        ecs.Collider.remove(world, eid)
      }

      const remainingQuery = ecs.defineQuery([block])
      const remaining = remainingQuery(world)
      if (remaining.length === 2) {
        world.events.dispatch(customUi, 'clear')
      }

      setTimeout(() => {
        const remaining_ = remainingQuery(world)
        if (remaining_.length === 1) {
          world.events.dispatch(customUi, 'clear')
        }
      }, 1000)

      setTimeout(() => {
        world.deleteEntity(eid)

        const remaining_ = remainingQuery(world)
        if (remaining_.length === 1) {
          world.events.dispatch(customUi, 'clear')
        }
      }, 5000)
    }

    // This listener logs a message whenever the entity collides with another entity.
    world.events.addListener(eid, ecs.physics.COLLISION_END_EVENT, handleCollision)
  },
  tick: (world, component) => {
    // Runs every frame.
  },
  remove: (world, component) => {
  },
})

export {block, handleCollision}

Hi!

It looks like the issue is coming from the asset path not resolving correctly, which is strange since you said it looks fine. Can you try changing the resourceUrl to assets/particle.glb and see if that stops the error from showing up? Can you also confirm that particle.glb is an asset in your project?

1 Like

I changed it to assets/particle.glb and the error disappeared.
It’s an elementary mistake…shame on me.
Thank you very much!

This topic was automatically closed 4 days after the last reply. New replies are no longer allowed.