2017-11-11 4 views
0

Ich bin neu in ARKit und ich versuche, eine relativ einfache App zu machen, wo Sie eine "Wand" erstellen und der Benutzer "wirft" Bälle auf, und es springt zurück .SceneKit Physik funktioniert nicht richtig in ARKit

Ich schaffe die Wand als SCNPlane, wo der Benutzer die Kamera zeigt so mögen:

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 
} 

ich die Richtung und Position der Kamera mit dieser Funktion erhalten:
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) 
} 

Ich erstelle Instanzen von Ball() und wirf sie so:

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) 

The Ball Klasse:

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))   
    } 
} 

Das Problem ist, dass viele Male, statt der Ball die Wand tatsächlich trifft, wird es nur durch sie reisen, als ob der Physik Körper nicht richtig funktioniert. Mir ist aufgefallen, dass es manchmal besser funktioniert, wenn ich den Abstand und Winkel zwischen Kamera und Wand verändere, aber die Ergebnisse sind nie so konsistent, wie ich es versucht habe.
Ich habe auch versucht, die Wandposition zu ändern: , um es genau 1 Meter tief vom Weltursprung zu positionieren, und die Ergebnisse waren etwas besser, aber immer noch nicht konsistent.

Wo könnte das Problem liegen und warum?
Vielen Dank im Voraus!

+0

haben Sie es geschafft, dies zu lösen? –

+0

@mike_t leider noch nicht: / – Eilon

Antwort

1

Richten Sie Ihre Wandphysik so kinematisch aus, dass der Ball damit reagieren kann.

  • Statische Objekte reagieren nicht mit irgendetwas.

  • Kinematische Objekte reagieren mit anderen Objekten, aber andere Objekte beeinflussen sie nicht.

  • Dynamisch bedeutet natürlich, dass es in beide Richtungen funktioniert.

Verwandte Themen