我正在尝试在Scenekit中实现第一人称太空射击游戏,并且遇到了一个(熟悉的,我知道的)物理仿真与物理仿真应该表示的SCNNodes的实际位置和变换相匹配的问题。
敌方无人飞船是使用此功能创建的,该功能将节点放置在一个名为SectorObjectNode的SCNnode中,该节点包含飞船外部的所有游戏对象(敌人,星星等)及其鱼雷(两者均位于场景的根节点中):
func spawnDrone(_ sender: UIButton) {
let humonshipScene = SCNScene(named: "Humon.scn")
let humonShip = humonshipScene?.rootNode.childNodes[0]
self.enemyDrone = humonShip
let droneShape = SCNBox(width: 10, height: 5, length: 5, chamferRadius: 0)
let dronePhysicsShape = SCNPhysicsShape(geometry: droneShape, options: nil)
self.enemyDrone?.physicsBody = SCNPhysicsBody(type: .dynamic, shape: dronePhysicsShape)
self.enemyDrone?.physicsBody?.isAffectedByGravity = false
self.enemyDrone?.physicsBody?.friction = 0
self.enemyDrone?.physicsBody?.categoryBitMask = 0b00000010
self.enemyDrone?.physicsBody?.contactTestBitMask = 0b00000010
self.enemyDrone?.name = "drone"
self.enemyDrone?.pivot = SCNMatrix4MakeTranslation(0.5, 0.5, 0.5)
self.enemyDrone?.position = SCNVector3Make(0, 0, -30)
self.enemyDrone?.scale = SCNVector3Make(1, 1, 1)
let actualPosition = self.scene.rootNode.convertPosition((self.enemyDrone?.position)!, from: self.enemyDrone)
self.enemyDrone?.position = self.scene.rootNode.convertPosition(actualPosition, to: self.sectorObjectsNode)
self.sectorObjectsNode.addChildNode(self.enemyDrone!)
}
使用以下代码,可响应屏幕上的操纵杆来旋转ectorObjectsNode(从而绕着船旋转“宇宙”以模拟运动):
func turnShip() {
self.rotate(self.sectorObjectsNode, around: SCNVector3Make(1, 0, 0), by: CGFloat(self.yThrust))
self.rotate(self.sectorObjectsNode, around: SCNVector3Make(0, 1, 0), by: CGFloat(self.xThrust))
}
func rotate(_ node: SCNNode, around axis: SCNVector3, by angle: CGFloat) {
let rotation = SCNMatrix4MakeRotation(Float(angle), axis.x, axis.y, axis.z)
let newTransform = SCNMatrix4Mult(node.worldTransform, rotation)
// Set the new transform
if let parent = node.parent {
node.transform = parent.convertTransform(newTransform, from: nil)
} else {
node.transform = newTransform
}
}
但是此代码会导致物理模拟重置(屏幕中央的灰色框是当sceneView.debugOptions设置为.showPhysicsShapes时引擎所描绘的无人机的物理边界框),结果如下:
我尝试在旋转之前捕获无人机的显示位置,然后在两个旋转功能之后应用它,但这会导致船向左下移动。我受困于如何使无人机的物理模拟(我将其专门用于碰撞检测)来坚持敌人敌机节点的实际位置。
和往常一样,问题是RTFM。我将物理物体设置为错误的类型:
self.enemyDrone?.physicsBody = SCNPhysicsBody(type: .dynamic, shape: dronePhysicsShape)
需要更改为
self.enemyDrone?.physicsBody = SCNPhysicsBody(type: .kinematic, shape: dronePhysicsShape)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句