问题描述
我正在尝试播放声音,然后在使用 Sceneform 发生碰撞时销毁两种不同类型的两个对象.我看到 Sceneform 有一个碰撞 api (https://developers.google.com/ar/reference/java/com/google/ar/sceneform/collision/package-summary),但我不知道如何处理碰撞.我试过扩展碰撞形状,覆盖 shapeIntersection 方法,并为每个节点设置碰撞形状属性,但这似乎没有任何作用.似乎没有任何示例代码,但文档中提到了碰撞侦听器.到目前为止,我一直在用蛮力方式进行检查,但我希望有一种更有效的方法.
I'm trying to play a sound and then destroy two objects of two different types when they collide using Sceneform. I see that Sceneform has a collision api (https://developers.google.com/ar/reference/java/com/google/ar/sceneform/collision/package-summary), but I can't figure out how to act on a collision. I've tried extending a collision shape, overriding the shapeIntersection methods, and setting the Collision Shape property for each node, but that doesn't seem to do anything. There doesn't seem to be any sample code, but the documentation mentions collision listeners. So far, I've just been doing checks the brute force way, but I was hoping there was a more efficient way.
我一直在尝试做这样的事情:
I've been trying to do something like this:
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 从相机抛出"到平面上的某个点.
Where a PassiveNode lies on a plane and the ActiveNode is "thrown" from the camera to a point on a plane.
推荐答案
您尝试覆盖的相交方法会计算两个碰撞形状是否相交,我建议不要覆盖它们.
The intersection methods you are trying to override do the math to calculate if two collision shapes are intersecting, I recommend against overriding them.
目前,没有您可以重写的侦听器或方法来检测节点何时重叠.但是,您可以调用一些函数来测试重叠节点.
Currently, there is no listener or method you can override to detect when nodes overlap. However, there are functions you can call to test for overlapping nodes.
您可以使用 Scene.overlapTest 或 Scene.overlapTestAll,它使用来自节点的 CollisionShape.
You can use Scene.overlapTest or Scene.overlapTestAll, which uses the CollisionShape from the Node.
默认情况下,它会根据附加到节点的可渲染对象的尺寸自动使用碰撞形状.您可以使用 Node.setCollisionShape 覆盖节点的碰撞形状,或在没有可渲染的节点上设置碰撞.
By default, it will automatically use a collision shape based on the dimensions of the Renderable attached to the Node. You can use Node.setCollisionShape to override the collision shape for the node, or to set collisions on a Node that doesn't have a Renderable.
您可以通过执行以下操作来实现您正在寻找的效果:
You can achieve the effect you are looking for by doing something like this:
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.
}
}
}
这篇关于场景形式碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!