我正在尝试播放声音然后在使用Sceneform发生碰撞时销毁两种不同类型的对象。我看到Sceneform有一个碰撞api(https://developers.google.com/ar/reference/java/com/google/ar/sceneform/collision/package-summary),但我无法弄清楚如何对碰撞做出反应。我已经尝试扩展碰撞形状,覆盖shapeIntersection方法,并为每个节点设置Collision Shape属性,但这似乎没有做任何事情。似乎没有任何示例代码,但文档提到了冲突侦听器。到目前为止,我一直在用蛮力的方式进行检查,但我希望有一种更有效的方法。
编辑:我一直在努力做这样的事情:public class PassiveNode extends Node{
public PassiveNode() {
PassiveCollider passiveCollider = new PassiveCollider(this);
passiveCollider.setSize(new Vector3(1, 1, 1));
this.setCollisionShape(passiveCollider);
}
public class PassiveCollider extends Box {
public Node node; // Remeber Node this is attached to
public PassiveCollider(Node node) {
this.node = node;
}
}
}
public class ActiveNode extends Node {
private Node node;
private Node target;
private static final float metersPerSecond = 1F;
public ActiveNode(Node target) {
node = this;
this.target = target;
BallCollision ball = new BallCollision();
ball.setSize(new Vector3(1, 1, 1));
this.setCollisionShape(ball);
}
@Override
public void onUpdate(FrameTime frameTime) {
super.onUpdate(frameTime);
Vector3 currPos = this.getWorldPosition();
Vector3 targetPos = target.getWorldPosition();
Vector3 direction = Vector3.subtract(targetPos, currPos).normalized();
this.setWorldPosition(Vector3.add(currPos, direction.scaled(metersPerSecond * frameTime.getDeltaSeconds())));
}
private class BallCollision extends Box {
@Override
protected boolean boxIntersection(Box box) {
if (box instanceof PassiveNode.PassiveCollider) {
//Play Sound
node.setEnabled(false);
((PassiveNode.PassiveCollider) box).node.setEnabled(false);
return true;
}
return false;
}
}
}
当PassiveNode位于一个平面上并且ActiveNode从相机“抛出”到一个平面上时。
答案 0 :(得分:2)
你试图覆盖的交集方法做数学来计算两个碰撞形状是否相交,我建议不要覆盖它们。
目前,没有可以覆盖的侦听器或方法来检测节点何时重叠。但是,您可以调用函数来测试重叠节点。
您可以使用Scene.overlapTest或Scene.overlapTestAll,它使用节点中的CollisionShape。
默认情况下,它会根据附加到节点的Renderable的尺寸自动使用碰撞形状。您可以使用Node.setCollisionShape覆盖节点的碰撞形状,或者在没有可渲染的节点上设置碰撞。
你可以通过这样的方式达到你想要的效果:
private void onUpdate(FrameTime frameTime) {
ArrayList<Node> overlappedNodes = arSceneView.getScene().overlapTestAll(ballNode);
for (Node node : overlappedNodes) {
if (node instanceof PassiveNode) {
// May want to use a flag to check that the node wasn't overlapping the previous frame.
// Play sound if overlapping started.
}
}
}