J'ai cherché partout pour ça mais je suis vide. Comment reproduisez-vous ce que Chris Lattner montrait avec Playgrounds et SceneKit à la WWDC? Je veux avoir une scène SceneKit, animée, dans Playgrounds.
J'ai essayé de couper et de coller le code d'installation du modèle de projet SceneKit, pensant que le rendu commencerait comme par magie, mais ce n'est pas le cas.
J'ai essayé de regarder la keynote et de m'arrêter et de zoomer sur l'écran de Lattner à la recherche d'indices sur le code source, mais il semblait importer tout son code d'ailleurs dans son projet, donc cela ne m'a donné aucun indice. Il ne semble rien y avoir dans la documentation, ou ça me manque.
Étant donné que Swift n'a pas de compatibilité source entre les versions, le code dans cette réponse peut ne pas fonctionner dans les versions futures ou précédentes de Swift. Il est actuellement mis à jour pour fonctionner dans Xcode 7.0 Playgrounds avec = Swift 2.0.
Le framework XCPlayground
est ce dont vous avez besoin, et il est documenté ici .
Voici une scène très simple pour vous aider à démarrer avec Scene Kit dans Swift:
import Cocoa // (or UIKit for iOS)
import SceneKit
import QuartzCore // for the basic animation
import XCPlayground // for the live preview
// create a scene view with an empty scene
var sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
var scene = SCNScene()
sceneView.scene = scene
// start a live preview of that view
XCPShowView("The Scene View", view: sceneView)
// default lighting
sceneView.autoenablesDefaultLighting = true
// a camera
var cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(x: 0, y: 0, z: 3)
scene.rootNode.addChildNode(cameraNode)
// a geometry object
var torus = SCNTorus(ringRadius: 1, pipeRadius: 0.35)
var torusNode = SCNNode(geometry: torus)
scene.rootNode.addChildNode(torusNode)
// configure the geometry object
torus.firstMaterial?.diffuse.contents = NSColor.redColor() // (or UIColor on iOS)
torus.firstMaterial?.specular.contents = NSColor.whiteColor() // (or UIColor on iOS)
// set a rotation axis (no angle) to be able to
// use a nicer keypath below and avoid needing
// to wrap it in an NSValue
torusNode.rotation = SCNVector4(x: 1.0, y: 1.0, z: 0.0, w: 0.0)
// animate the rotation of the torus
var spin = CABasicAnimation(keyPath: "rotation.w") // only animate the angle
spin.toValue = 2.0*M_PI
spin.duration = 3
spin.repeatCount = HUGE // for infinity
torusNode.addAnimation(spin, forKey: "spin around")
Lorsque je l'exécute, cela ressemble à ceci:
Notez que pour exécuter Scene Kit dans un terrain de jeu iOS , vous devez cocher la case "Exécuter dans le simulateur complet".
Vous trouverez le paramètre Playground dans le volet Utilitaires (⌥⌘ cacher ou montrer)
Pour faire fonctionner le terrain de jeu avec iOS comme cible et utiliser le dernier Xcode 8.1, je l'ai fait fonctionner avec les modifications suivantes du code original de David Rönnqvist.
import UIKit
import SceneKit
import QuartzCore // for the basic animation
import PlaygroundSupport
// create a scene view with an empty scene
var sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
var scene = SCNScene()
sceneView.scene = scene
PlaygroundPage.current.liveView = sceneView
// default lighting
sceneView.autoenablesDefaultLighting = true
// a camera
var cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(x: 0, y: 0, z: 3)
scene.rootNode.addChildNode(cameraNode)
// a geometry object
var torus = SCNTorus(ringRadius: 1, pipeRadius: 0.35)
var torusNode = SCNNode(geometry: torus)
scene.rootNode.addChildNode(torusNode)
// configure the geometry object
torus.firstMaterial?.diffuse.contents = UIColor.red
torus.firstMaterial?.specular.contents = UIColor.white
// set a rotation axis (no angle) to be able to
// use a nicer keypath below and avoid needing
// to wrap it in an NSValue
torusNode.rotation = SCNVector4(x: 1.0, y: 1.0, z: 0.0, w: 0.0)
// animate the rotation of the torus
var spin = CABasicAnimation(keyPath: "rotation.w") // only animate the angle
spin.toValue = 2.0*M_PI
spin.duration = 3
spin.repeatCount = HUGE // for infinity
torusNode.addAnimation(spin, forKey: "spin around")
Les principales choses que vous devez faire différemment sont:
liveView
du terrain de jeu et,Élargir la réponse de Moshe.
Si cette combinaison de touches ne fonctionne pas pour vous, essayez d’aller dans la barre de menus et sélectionnez Afficher> Editeur adjoint> Afficher l’assistant.
Dans Xcode 10.2, il y a un framework PlaygroundSupport
. Il partage les données d'une aire de jeux, gère les vues en direct et contrôle l'exécution d'une aire de jeux.
import PlaygroundSupport
Vous pouvez utiliser Playground Support depuis les aires de jeux pour:
Vous pouvez également utiliser
PlaygroundSupport
pour afficher et fermer les vues en direct, qui montrent les résultats de l'exécution du code dans une aire de jeux. Vous pouvez créer des vues en direct pour vos propres types en tirant parti des représentations de vue en direct intégrées disponibles sur de nombreux types existants. Les vues en direct traditionnelles sont disponibles dans les aires de jeux dans Xcode et dans Swift Playgrounds. Elles s'exécutent selon le même processus que le code dans l'aire de jeux, afin que vous puissiez accéder à leurs propriétés et méthodes comme d'habitude; cependant, elles est réinitialisé à chaque fois que vous exécutez le terrain de jeu. La vue en direct toujours active dans Swift Playgrounds, activée lorsque vous ajoutez LiveView.Swift à une page, s'exécute selon son propre processus afin que vous puissiez conserver les informations et les visuels entre les exécutions successives. La vue en direct toujours active n'est pas réinitialisée tant que vous ne quittez pas la page.
J'ai légèrement modifié le code:
import PlaygroundSupport
import UIKit
import SceneKit
import QuartzCore
var sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 1000, height: 200))
var scene = SCNScene()
sceneView.scene = scene
sceneView.backgroundColor = .black
PlaygroundPage.current.liveView = sceneView
var lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light?.type = .directional
lightNode.light?.intensity = 3000
lightNode.light?.shadowMode = .deferred
lightNode.rotation = SCNVector4(x: 0, y: 0, z: 0.5, w: 1.5 * Float.pi)
scene.rootNode.addChildNode(lightNode)
var cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(x: 2.5, y: 0, z: 5)
scene.rootNode.addChildNode(cameraNode)
var box = SCNBox(width: 3, height: 3, length: 3, chamferRadius: 0.4)
var boxNode = SCNNode(geometry: box)
scene.rootNode.addChildNode(boxNode)
box.firstMaterial?.diffuse.contents = UIColor.blue
box.firstMaterial?.specular.contents = UIColor.purple
boxNode.rotation = SCNVector4(x: 1.0, y: 1.0, z: 0.0, w: 0.0)
boxNode.scale = SCNVector3(x: 1.0, y: 1.0, z: 1.0)
var spin = CABasicAnimation(keyPath: "rotation.w")
var scale = CABasicAnimation(keyPath: "scale.x")
spin.toValue = 3 * -CGFloat.pi
spin.duration = 2
spin.repeatCount = .greatestFiniteMagnitude
scale.toValue = 1.5
scale.duration = 2
scale.repeatCount = .infinity
boxNode.addAnimation(spin, forKey: "spin around")
boxNode.addAnimation(scale, forKey: "scale x")
Si le terrain de jeu se plaint de `` int n'est pas convertible en CGFloat '', vous pouvez utiliser cette ligne de code:
spin.toValue = NSValue(SCNVector4: SCNVector4(x: 1, y: 1, z: 0, w: CGFloat(2.0*M_PI)))
Les transtypages implicites ne semblent pas être définis dans Swift.