我正在尝试使用Xcode游戏中的代码作为Swift Playground。该代码在Xcode版本中完美运行,但在操场上,我收到错误:
无法将'UIView'(0x114debe38)类型的值转换为'SCNView'(0x12521d3d0)。
类的类型设置为UIViewController
类型,所以我不确定为什么这不仅仅在操场上有效。我在应用程序和游乐场都有相同的文件。
我已经看过this question了,但这个方法似乎已经内置了。
我还尝试将它转换回UIView,如果它是SCNView,我也尝试创建一个新视图,将子视图添加为SCNView,然后将最终视图设置为新视图。我的尝试都没有奏效。
class GameScene: UIViewController {
let finalView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
// create a new scene
let scene = SCNScene(named: "art.scnassets/ship.scn")!
// create and add a camera to the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
// place the camera
cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
cameraNode.rotation = SCNVector4(0, 0, 0, 30)
// create and add a light to the scene
let lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light!.type = .omni
lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
scene.rootNode.addChildNode(lightNode)
// create and add an ambient light to the scene
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = .ambient
ambientLightNode.light!.color = UIColor.darkGray
scene.rootNode.addChildNode(ambientLightNode)
// retrieve the shark node
let shark = scene.rootNode.childNode(withName: "ship", recursively: true)!
// animate the 3d object
//shark.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: 2, z: 0, duration: 1)))
// retrieve the SCNView
let scnView = self.view as! SCNView
// set the scene to the view
scnView.scene = scene
// allows the user to manipulate the camera
scnView.allowsCameraControl = true
// show statistics such as fps and timing information
scnView.showsStatistics = true
// configure the view
scnView.backgroundColor = UIColor.black
// add a tap gesture recognizer
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
scnView.addGestureRecognizer(tapGesture)
}
@objc
func handleTap(_ gestureRecognize: UIGestureRecognizer) {
// retrieve the SCNView
let scnView = self.view as! SCNView
finalView.addSubview(scnView)
// check what nodes are tapped
let p = gestureRecognize.location(in: scnView)
let hitResults = scnView.hitTest(p, options: [:])
// check that we clicked on at least one object
if hitResults.count > 0 {
// retrieved the first clicked object
let result = hitResults[0]
// get its material
let material = result.node.geometry!.firstMaterial!
// highlight it
SCNTransaction.begin()
SCNTransaction.animationDuration = 0.5
// on completion - unhighlight
SCNTransaction.completionBlock = {
SCNTransaction.begin()
SCNTransaction.animationDuration = 0.5
material.emission.contents = UIColor.black
SCNTransaction.commit()
}
material.emission.contents = UIColor.red
SCNTransaction.commit()
}
}
override var shouldAutorotate: Bool {
return true
}
override var prefersStatusBarHidden: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .pad {
return .allButUpsideDown
} else {
return .all
}
}
}
PlaygroundSupport.PlaygroundPage.current.liveView = GameScene()
这应该显示的是一个3D模型和一个可以通过移动设备上的触摸平移它的相机。
在您的示例中,UIViewController视图可能已设置为界面构建器中的SCNView。如果你没有使用笔尖,你可以通过覆盖loadView
来做到这一点。
override func loadView() {
let scnView = SCNView(frame: UIScreen.main.bounds, options: nil)
self.view = scnView
}