excaliburjs / Excalibur

šŸŽ® Your friendly TypeScript 2D game engine for the web šŸ—”ļø
https://excaliburjs.com
BSD 2-Clause "Simplified" License
1.8k stars 190 forks source link

Child actor does not inherit parent's scene #2579

Closed ivanjermakov closed 1 year ago

ivanjermakov commented 1 year ago

Steps to Reproduce

const engine = new Engine()
const a = new Actor({name: 'A'})
engine.add(a)
const b = new Actor({name: 'B'})
a.addChild(b)
console.log(a.scene, b.scene)

Expected Result

Log the same Scene object two times

Actual Result

Scene {...} null

Environment

Workaround

Set child's scene manually:

const a = new Actor({name: 'A'})
engine.add(a)
const b = new Actor({name: 'B'})
a.addChild(b)
b.scene = a.scene
console.log(a.scene, b.scene)

Possible fix

Populate the actor's scene upon adding it as a child:

src/engine/EntityComponentSystem/Entity.ts:232

public addChild(entity: Entity): Entity {
  if (entity.parent === null) {
    if (this.getAncestors().includes(entity)) {
      throw new Error('Cycle detected, cannot add entity');
    }
    if (entity.scene === null) {
      entity.scene = this.scene;  //<---- populate child's scene
    }
    this._children.push(entity);
    entity._parent = this;
    this.childrenAdded$.notifyAll(entity);
  } else {
    throw new Error('Entity already has a parent, cannot add without unparenting');
  }
  return this;
}

It kind of related to #2419, but was not fixed there.

eonarheim commented 1 year ago

@ivanjermakov Definitely a bug!

eonarheim commented 1 year ago

Hi @ivanjermakov I did some digging and I think the latest main includes a fix for this f8d818a39415adc1bcb458635a1c7b0960f4c05d

You can work off the latest alpha builds in npm for this fix šŸ‘ https://www.npmjs.com/package/excalibur?activeTab=versions

I'm going to post a PR that includes the test case you proposed as well.