Hi all,
I’m new to 8th Wall Studio, and I’m trying to create a simple spawner. However, I’m having trouble attaching components to new entities created at runtime. I’ve looked through the documentation and forums but couldn’t find anything related to my issue.
I have a custom component that moves an entity. When I attach it to an entity in the Studio, it works as expected.
The issue arises with a spawner that creates a new entity at runtime.
The entity is created, and I can see it in the hierarchy, but none of the components seem to be attached.
To create and configure the new entity, I’m using the following code:
const newEid = world.createEntity()
world.setParent(newEid, data.parentEntity) //data.parentEntity exists from the schema
world.setPosition(newEid, 1.45, 0.68, 15)
world.setScale(newEid, 1, 1, 1)
ecs.BoxGeometry.set(world, newEid, {width: 1, height: 1, depth: 1})
ecs.Material.set(world, newEid, {
r: 0,
g: 0,
b: 255,
})
soldier.set(world, newEid) //custom component, it should move the box
console.log(newEid) // some id
console.log(world.getParent(newEid)) // 0n
console.log(Array.from(world.getChildren(data.parentEntity))) // newEid not here
The new entity doesn’t seem to have any of the components. When I inspect it in the Studio, its transform shows default values, and it doesn’t appear to be attached to the correct parent.
Do you have any suggestion, or is there something I misunderstood or missed?
Thanks a lot
Full code below
Spawner
import * as ecs from '@8thwall/ecs'
import {soldier} from './soldier'
const deployButton = ecs.registerComponent({
name: 'deploy-button',
schema: {
entityToSpawn: ecs.eid,
parentEntity: ecs.eid,
},
stateMachine: ({world, eid, schemaAttribute, dataAttribute}) => {
const spawnState = ecs.defineState('spawn').onEnter(() => {
const data = schemaAttribute.acquire(eid)
const newEid = world.createEntity()
world.setParent(newEid, data.parentEntity)
world.setPosition(newEid, 1.45, 0.68, 15)
world.setScale(newEid, 1, 1, 1)
ecs.BoxGeometry.set(world, newEid, {width: 1, height: 1, depth: 1})
ecs.Material.set(world, newEid, {
r: 0,
g: 0,
b: 255,
})
soldier.set(world, newEid)
console.log(newEid) // some id
console.log(world.getParent(newEid)) // 0n
console.log(Array.from(world.getChildren(data.parentEntity))) // newEid not here
}).onExit(() => {
console.log('exit spawn')
})
const toSpawn = ecs.defineTrigger()
const defaultState = ecs.defineState('default').initial().onEnter(() => {
console.log('entered default')
}).onTick(() => {
if (world.input.getAction('deploy')) {
toSpawn.trigger()
}
})
.onTrigger(toSpawn, spawnState)
.onExit(() => {
console.log('exit default')
})
},
})
export {deployButton}
Custom component
import * as ecs from '@8thwall/ecs' // This is how you access the ecs library.
const soldier = ecs.registerComponent({
name: 'soldier',
schema: {
walkingSpeed: ecs.f32,
},
schemaDefaults: {
walkingSpeed: 0,
},
data: {
walkingSpeed: ecs.f32,
},
stateMachine: ({world, eid, dataAttribute}) => {
const moveSoldier = () => {
const data = dataAttribute.acquire(eid)
data.walkingSpeed -= 0.4
ecs.physics.applyForce(world, eid, 0, 0, data.walkingSpeed)
dataAttribute.commit(eid)
}
const walkingState = ecs.defineState('walking').onEnter(() => {
console.log('i\'m walking here')
})
.onTick(() => {
moveSoldier()
})
.onExit(() => {
console.log('Not walking naymore')
})
const startWalking = ecs.defineTrigger()
ecs.defineState('default').initial()
.onTrigger(startWalking, walkingState)
.onTick(() => {
startWalking.trigger()
})
},
})
export {soldier}