前言
SceneKit使用SCNPhysicsWorld來管理這種物理模擬,讓物體的碰撞、連接、掉落等具有真實(shí)感。
SCNPhysicsBody:想要一個(gè)SCNNode參與到物理模擬中,只需要給node.physicsBody賦值一個(gè)合適的值,SCNPhysicsBody有三種類型
-
dynamic: 動(dòng)態(tài)的物體,受力的影響(applyForce)。 -
static: 靜態(tài)的物體,不受力的影響,且不能移動(dòng)。適合場(chǎng)景中地面、墻體等。 -
kinematic: 不受碰撞、力影響,在空間變換中,會(huì)對(duì)dynamic的物體產(chǎn)生力的影響。
實(shí)踐
override func viewDidLoad() {
super.viewDidLoad()
let sceneView = SCNView(frame: view.bounds)
sceneView.backgroundColor = UIColor.black
sceneView.scene = SCNScene()
sceneView.allowsCameraControl = true
sceneView.showsStatistics = true
//設(shè)置運(yùn)動(dòng)速度
sceneView.scene?.physicsWorld.speed = 5
view.addSubview(sceneView)
//添加照相機(jī)
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(0, 10, 20)
// 因?yàn)橐@示地板 多以要傾斜一點(diǎn)角度(繞X軸旋轉(zhuǎn),繞哪個(gè)軸旋轉(zhuǎn)哪個(gè)軸的值就為1)
cameraNode.rotation = SCNVector4(1, 0, 0, -Double.pi * 0.1)
cameraNode.camera?.automaticallyAdjustsZRange = true
sceneView.scene?.rootNode.addChildNode(cameraNode)
//添加地板
let floorNode = SCNNode()
let floor = SCNFloor()
floor.firstMaterial?.diffuse.contents = "floor.jpg"
floorNode.geometry = floor
// 如果沒有這一行代碼,柱狀物體會(huì)直接下沉到不見為止
floorNode.physicsBody = SCNPhysicsBody.static()
sceneView.scene?.rootNode.addChildNode(floorNode)
// 添加動(dòng)態(tài)事物
for _ in 0..<10 {
let box = SCNBox(width: 0.5, height: 3, length: 1, chamferRadius: 0)
box.firstMaterial?.diffuse.contents = "1.PNG"
let node = SCNNode(geometry: box)
node.physicsBody = SCNPhysicsBody.dynamic()
node.position = SCNVector3(Float(arc4random_uniform(5)) - 2, 1.5, Float(arc4random_uniform(5)))
sceneView.scene?.rootNode.addChildNode(node)
}
// 繼續(xù)添加動(dòng)態(tài)事物
for _ in 0..<5 {
let node = SCNNode()
let sphere = SCNSphere(radius: 1)
sphere.firstMaterial?.diffuse.contents = "sun.jpg"
node.geometry = sphere
node.physicsBody = SCNPhysicsBody.dynamic()
node.position = SCNVector3(Float(arc4random_uniform(5)) - 2, 10, Float(arc4random_uniform(5)))
sceneView.scene?.rootNode.addChildNode(node)
}
}
-
效果圖
碰撞.gif

碰撞.gif
