Skip to content

【物理】在 onTriggerXXX 中执行销毁节点操作,会触发报错 #2877

@cptbtptpbcptdtptp

Description

@cptbtptpbcptdtptp

示例:

/**
 * @title Trigger Destroy Repro
 * @category Physics
 * @thumbnail https://mdn.alipayobjects.com/merchant_appfe/afts/img/A*omVHSr3cHpIAAAAAAAAAAAAADiR2AQ/original
 */
import {
  BoxColliderShape,
  Camera,
  ColliderShape,
  Color,
  DirectLight,
  DynamicCollider,
  Entity,
  MeshRenderer,
  PBRMaterial,
  PrimitiveMesh,
  Script,
  Vector3,
  WebGLEngine
} from "@galacean/engine";
import { LitePhysics } from "@galacean/engine-physics-lite";

class DestroyOnTrigger extends Script {
  target: Entity | null = null;
  private _fired = false;

  onTriggerEnter(other: ColliderShape): void {
    if (this._fired || !this.target) {
      return;
    }
    this._fired = true;
    console.log(`[TriggerA] onTriggerEnter with ${other.collider?.entity?.name ?? "unknown"}`);
    // Destroying the other entity here reproduces the null collider entity crash.
    this.target.destroy();
  }
}

class LogTrigger extends Script {
  onTriggerEnter(other: ColliderShape): void {
    console.log(`[TriggerB] onTriggerEnter with ${other.collider?.entity?.name ?? "unknown"}`);
  }
}

main();

async function main(): Promise<void> {
  const engine = await WebGLEngine.create({ canvas: "canvas", physics: new LitePhysics() });
  engine.canvas.resizeByClientSize();

  const rootEntity = engine.sceneManager.activeScene.createRootEntity("Root");

  const cameraEntity = rootEntity.createChild("Camera");
  cameraEntity.transform.setPosition(0, 2.5, 6);
  cameraEntity.transform.lookAt(new Vector3(0, 0, 0));
  cameraEntity.addComponent(Camera);

  const lightEntity = rootEntity.createChild("Light");
  lightEntity.transform.setPosition(3, 3, 3);
  lightEntity.transform.lookAt(new Vector3(0, 0, 0));
  lightEntity.addComponent(DirectLight);

  const triggerA = createTriggerBox(rootEntity, "TriggerA", new Vector3(0, 0, 0), new Color(0.9, 0.2, 0.2, 1));
  const triggerB = createTriggerBox(rootEntity, "TriggerB", new Vector3(0.25, 0, 0), new Color(0.2, 0.9, 0.2, 1));

  const destroyScript = triggerA.addComponent(DestroyOnTrigger);
  destroyScript.target = triggerB;
  triggerB.addComponent(LogTrigger);

  engine.run();
}

function createTriggerBox(root: Entity, name: string, position: Vector3, color: Color): Entity {
  const entity = root.createChild(name);
  entity.transform.position.copyFrom(position);

  const renderer = entity.addComponent(MeshRenderer);
  renderer.mesh = PrimitiveMesh.createCuboid(root.engine, 1, 1, 1);
  const material = new PBRMaterial(root.engine);
  material.baseColor = color;
  renderer.setMaterial(material);

  const collider = entity.addComponent(DynamicCollider);
  const shape = new BoxColliderShape();
  collider.addShape(shape);

  return entity;
}

Metadata

Metadata

Assignees

Labels

physicsEngine's physical system

Type

Projects

Status

To do

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions