[英]How can I reset an SCNNode's SCNPhysicsBody without resetting the SCNNode's position?
[英]Node group's position is reset at the start of SCNNode.runAction
我有一些代碼可以在屏幕被點擊時圍繞x軸旋轉幾個SCNNode:
func handleTap(gestureRecognize: UIGestureRecognizer) {
let sceneView = self.view as SCNView
let slice = self.cubes[0...8]
let container = SCNNode()
for node: SCNNode in slice {
container.addChildNode(node)
}
sceneView.scene!.rootNode.addChildNode(container)
container.runAction(SCNAction.rotateByX(CGFloat(M_PI / 2), y: 0.0, z: 0.0, duration: 1), completionHandler: { () -> Void in
println("complete")
})
}
我遇到的問題是,每次調用此函數時,節點似乎都會在執行操作之前將自身重置為原始位置。 操作完成后,它們似乎保持在正確的位置,直到再次點擊屏幕。 如何進行后續調用handleTap
將它們從當前位置旋轉?
我嘗試在將節點添加到容器之前從其原始父節點中刪除節點,但它沒有可見的效果。
我也試過用動畫
let spin = CABasicAnimation(keyPath: "rotation")
spin.fromValue = NSValue(SCNVector4: SCNVector4(x: -1, y: 0, z: 0, w: 0))
spin.toValue = NSValue(SCNVector4: SCNVector4(x: -1, y: 0, z: 0, w: Float(M_PI_2)))
spin.duration = 3
spin.repeatCount = .infinity
container.addAnimation(spin, forKey: "spin around")
其效果與動作完全相同。
如果我將節點作為根視圖的子節點放回runAction的完整塊中
container.runAction(action, completionHandler: { () -> Void in
println("completed rotation")
for node: SCNNode in slice {
node.removeFromParentNode()
sceneView.scene!.rootNode.addChildNode(node)
}
})
然后,節點在完成操作時返回到其原始位置,而不是在新點擊開始時。
從場景的根節點中刪除節點,添加到容器並旋轉時,將相對於容器的本地坐標系將變換應用於節點。 解決方案是將節點的變換從容器的坐標系轉換為根節點的坐標系,然后再將其添加回根節點。
func handleTap(gestureRecognize: UIGestureRecognizer) {
let sceneView = self.view as SCNView
let action = SCNAction.rotateByAngle(CGFloat(M_PI_2), aroundAxis: SCNVector3Make(-1, 0, 0), duration: 1)
let slice = self.cubes[0...8]
let container = SCNNode()
let root = sceneView.scene!.rootNode
for node: SCNNode in slice {
container.addChildNode(node)
}
root.addChildNode(container)
container.runAction(action, completionHandler: { () -> Void in
for node: SCNNode in slice {
let transform = node.parentNode!.convertTransform(node.transform, toNode: root)
node.removeFromParentNode()
node.transform = transform
root.addChildNode(node)
}
})
}
這是我在沒有容器或類似的東西的情況下旋轉SCNNode
:
let targetRotationRadians: CGFloat = targetRotationAngle * (CGFloat.pi / 180.0)
let rotationAction = SCNAction.rotateTo(x: 0.0, y: targetRotationRadians, z: 0.0, duration: animationDuration, usesShortestUnitArc: true)
yourSCNNode.runAction(rotationAction)
重要的是為SCNAction.rotateTo
方法設置usesShortestUnitArc
為true
。 這樣,節點在旋轉到所需角度之前不必返回其原始角度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.