我是ARKit
的新手,我正在尝试创建一个相对简单的应用程序,你创建一个“墙”,用户“抛出”它的球,然后它反弹回来。
我将墙创建为SCNPlane
,用户将相机指向这样:
private func createWall(withPosition position: SCNVector3) -> SCNNode {
let wallGeometry = SCNPlane(width: 0.3, height: 0.3)
wallGeometry.firstMaterial?.isDoubleSided = true
wallGeometry.firstMaterial?.diffuse.contents = UIColor.green.withAlphaComponent(0.7)
let parentNode = SCNNode(geometry: wallGeometry)
let (position, _) = cameraPosition()
parentNode.position = position
parentNode.physicsBody = SCNPhysicsBody(type: .static, shape: SCNPhysicsShape(geometry: wallGeometry, options: nil))
parentNode.physicsBody?.isAffectedByGravity = false
self.wall = parentNode
return parentNode
}
我用这个功能得到了相机的方向和位置:
cameraPosition():
func cameraPosition() -> (SCNVector3, SCNVector3) {
guard let frame = sceneView.session.currentFrame else { return (SCNVector3(0, 0, -1), (SCNVector3(0, 0, 0))) }
let matrix = SCNMatrix4(frame.camera.transform)
let direction = SCNVector3(-matrix.m31, -matrix.m32, -matrix.m33)
let location = SCNVector3(matrix.m41, matrix.m42, matrix.m43)
return ((location + direction), direction)
}
// Helper function
func +(left: SCNVector3, right: SCNVector3) -> SCNVector3 {
return SCNVector3(left.x + right.x, left.y + right.y, left.z + right.z)
}
我创建Ball()
的实例并像这样抛出它们:
let (position, direction) = cameraPosition()
// throw ball
let ball = Ball()
ball.position = position //SCNVector3(0,0,0)
sceneView.scene.rootNode.addChildNode(ball)
let impulseModifier = Float(10)
ball.physicsBody!.applyForce(SCNVector3(direction.x*impulseModifier, direction.y*impulseModifier, direction.z*impulseModifier), asImpulse: true)
Ball 类:
class Ball: SCNNode {
override init() {
super.init()
let sphere = SCNSphere(radius: 0.05)
sphere.firstMaterial?.diffuse.contents = UIColor.red
self.geometry = sphere
self.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(geometry: sphere, options: nil))
}
}
问题是,很多时候,它不是实际击中墙壁,而是穿过它,好像物理体不能正常运作。我注意到,当我改变相机和墙壁之间的距离和角度时,它会更好地工作,但结果从来没有像我尝试的那样一致。
我还尝试将墙壁位置改为:SCNVector3(0, 0, -1)
将其定位在距离世界原点 1 米的位置,结果稍微好一些,但仍然不一致。
问题出在哪里?为什么?
提前致谢!
2 回答
将您的墙体物理设置为运动学,以便球可以对其做出反应。
静态对象不会对任何东西做出反应。
运动对象与其他对象反应,但其他对象不会影响它们。
动态当然意味着它可以在两个方向上工作。
这很可能是因为球太小而无法使碰撞检测正常工作。尝试将continuousCollisionDetectionThreshold设置为等于球半径的一半。在这种情况下: