World event dispatch

Hello everyone. I’m working on a project in 8th wall. I’ve followed quite a few tutorials and gone through quite a few of the sample projects. I cannot seem to figure out how to properly use world events and dispatch to them.

import * as ecs from '@8thwall/ecs'
import {ClayPigeon} from './clayPigeon'
import {MouseButtons, MouseEvents} from './mouseControls'
const {THREE} = (window as any)

ecs.registerComponent({
  name: 'GameManager',
  schema: {
    shotsTakenDisplay: ecs.eid,
    shotsHitDisplay: ecs.eid,
    clayPigeonEntity: ecs.eid,
  },
  data: {
    score: ecs.i32,
    shotsTaken: ecs.i32,
    pigeon: ecs.eid,
  },
  add: (world, component) => {
    const {shotsTakenDisplay, clayPigeonEntity} = component.schema
    if (!clayPigeonEntity) {
      console.log('no pigeon entity')
    }

    function handleInteraction(event) {
      const raycaster = new THREE.Raycaster()
      const castPoint = new THREE.Vector2()
      castPoint.x = 0
      castPoint.y = 0
      raycaster.setFromCamera(castPoint, world.three.activeCamera)
      const pigeon = world.three.entityToObject.get(clayPigeonEntity)
      if (!pigeon) {
        console.error('Ground object not found for entity ID:', pigeon)
        return
      }
      // C is not a function?
      world.events.dispatch(world.events.globalId, 'shoot', this)
      const intersects = raycaster.intersectObject(pigeon, true)
      if (intersects.length > 0) {
        console.log('hit pigeon')
        world.events.dispatch(world.events.globalId, 'hitShot', this)
      }
    }
    window.addEventListener('click', handleInteraction)
  },

  stateMachine: ({world, eid, schemaAttribute, dataAttribute}) => {
    const shoot = () => {
      console.log('shoot')
      const data = dataAttribute.acquire(eid)
      data.score += 1
      ecs.Ui.set(world, schemaAttribute.get(eid).shotsTakenDisplay, {
        text: data.score.toString(),
      })
      dataAttribute.commit(eid)
    }
    const hitShot = () => {
      console.log('hit shot')
      const data = dataAttribute.acquire(eid)
      data.shotsTaken += 1
      ecs.Ui.set(world, schemaAttribute.get(eid).shotsTakenDisplay, {
        text: data.shotsTaken.toString(),
      })
      dataAttribute.commit(eid)
    }
    ecs.defineState('default').initial().onEnter(() => {
      world.events.addListener(world.events.globalId, 'shoot', this)
      world.events.addListener(world.events.globalId, 'hitShot', this)
    }).onExit(() => {
      world.events.removeListener(world.events.globalId, 'shoot', this)
      world.events.removeListener(world.events.globalId, 'hitShot', this)
    })
  },

})

This is my game manager class. I basically have two different events that I want to fire through the world event dispatcher. All they do right now is they should increment a score display on the screen.

However, when I try to fire any of these world events through world.events.dispatch, the editor throws an error: TypeError: C is not a function.

Any guidance as to what I’m doing wrong would be greatly appreciated.

I got the setup of this class from (6) Niantic Studio Workshop: Game Mechanics Basics - YouTube this workshop.

Your event dispatcher’s third argument should be an object with the data you want to send through the event. You can find more details in this guide.

For example, you might use something like this:

world.events.dispatch(world.events.globalId, 'shoot', {shooter: this})

However, I’m not certain if non-primitive data is supported when dispatching events. To be safe, I’d recommend sticking to primitive types rather than passing something like this. Here’s more information on primitive types.

I’ve solved this on my own merrit.

ecs.defineState('default').initial().onEnter(() => {
      world.events.addListener(world.events.globalId, 'shoot', shoot)
      world.events.addListener(world.events.globalId, 'hitShot', hitShot)
    }).onExit(() => {
      world.events.removeListener(world.events.globalId, 'shoot', shoot)
      world.events.removeListener(world.events.globalId, 'hitShot', hitShot)
    })

I was formatting the expression wrong. The tooltips in the editor are rather ambigious so it took some trial and error.

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