先來認(rèn)識(shí)下幾個(gè)類
SCNScene
場(chǎng)景圖 - 具有連接的幾何圖形迟蜜,燈光愧杯,照相機(jī)和其他屬性的節(jié)點(diǎn)的層次結(jié)構(gòu)碟嘴,這些節(jié)點(diǎn)在一起形成可顯示的3D場(chǎng)景。
---白話: 用于顯示3D場(chǎng)景的環(huán)境, 一個(gè)SCNScene對(duì)象代表三維場(chǎng)景及其內(nèi)容鼓拧。渲染用于顯示的場(chǎng)景
SCNView
用于顯示3D場(chǎng)景的視圖, 類似于UIView的功能
SCNNode
SCNNode是節(jié)點(diǎn)樹的模型類對(duì)象半火。它封裝了位置、旋轉(zhuǎn)和其他轉(zhuǎn)換的一個(gè)節(jié)點(diǎn),定義一個(gè)坐標(biāo)系季俩。
所有的子節(jié)點(diǎn)的坐標(biāo)系統(tǒng)是相對(duì)于他們的一個(gè)父節(jié)點(diǎn)钮糖。
3D場(chǎng)景是有一個(gè)一個(gè)的節(jié)點(diǎn)組成的, 每一個(gè)節(jié)點(diǎn)管理者場(chǎng)景中的一個(gè)物體, 如燈光, 幾何, 照相機(jī)等, 而scene又管理者所有的節(jié).點(diǎn)
節(jié)點(diǎn)本身是不可見的, 它僅代表一個(gè)坐標(biāo)空間變換(位置,方向和比例)相對(duì)于其父節(jié)點(diǎn)的場(chǎng)景酌住。要構(gòu)建場(chǎng)景藐鹤,您可以使用節(jié)點(diǎn)層次結(jié)構(gòu)來創(chuàng)建其結(jié)構(gòu),然后向節(jié)點(diǎn)添加燈光赂韵,照相機(jī)和幾何圖形娱节,以創(chuàng)建可見的內(nèi)容。
SCNCamera
觀察場(chǎng)景的視角,
要顯示場(chǎng)景中的內(nèi)容, 必須為節(jié)點(diǎn)指定一個(gè)SCNCamera對(duì)象
相機(jī)的視角始終沿著節(jié)點(diǎn)的局部坐標(biāo)系的負(fù)z軸祭示。
要在場(chǎng)景的不同部分將相機(jī)指向肄满,使用position,rotation,transform包含它的節(jié)點(diǎn)的屬性。
SCNGeometry
你可以從3D建模工具生成的.dae文件中加載一個(gè)幾何體质涛,也可以用代碼創(chuàng)建.
SceneKit 提供了幾種常見幾何體稠歉,是SCNGeometry的子類,比如長方體汇陆,球怒炸,圓柱球等等
接下來再了解SCNView的三個(gè)內(nèi)置屬性
顯示統(tǒng)計(jì)數(shù)據(jù)
scnView.showsStatistics = true
打開相機(jī)控制
//這個(gè)屬性是讓你的場(chǎng)景可以接受一些內(nèi)置的手勢(shì)操作, 比如放大縮小
scnView.allowsCameraControl = true
自動(dòng)啟用默認(rèn)光源
scnView.autoenablesDefaultLighting = true
自動(dòng)設(shè)置環(huán)境光, 默認(rèn)情況下, 如果沒有光是不會(huì)呈現(xiàn)任務(wù)物體的, 該屬性就是場(chǎng)景設(shè)置內(nèi)置的光照
OK, 知道里以上的知識(shí)下面就可以正式邊編碼了.
Xcode 8.3.3
新建一個(gè)工程選擇Game
next選擇SceneKit
然后next->create
在左側(cè)的目錄中, 有一個(gè)文件我們不熟悉, 那就是art.scnassets
這個(gè)文件是存放一些3D場(chǎng)景的資源文件, 就像Assets.xcassets
存放圖片文件一樣
現(xiàn)在運(yùn)行工程, 你將會(huì)看到一個(gè)繞著Y軸旋轉(zhuǎn)的飛機(jī)
這些都是Xcode為我們添加的模板, 為了搞清楚Xcode為我們做了什么, 我們要把這些模板的數(shù)據(jù)刪掉.
首先刪除art.scnassets
, 把他扔到垃圾簍
然后回到GameViewController.swift
, 刪除所有代碼, 只保留這些
import UIKit
import SceneKit
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
//控制屏幕旋轉(zhuǎn)
override var shouldAutorotate: Bool {
return true
}
//隱藏狀態(tài)欄
override var prefersStatusBarHidden: Bool {
return true
}
}
先聲明三個(gè)屬性
var scnView: SCNView!
var scnScene: SCNScene!
var cameraNode: SCNNode!
第一步:創(chuàng)建一個(gè)SCNView
SCNView可以代碼創(chuàng)建也可以從storyboard中間在, 我們剛才創(chuàng)建的工程, 默認(rèn)是從storyboard中加載的. ViewController的View是繼承自SCNView的
func setupView() {
scnView = self.view as! SCNView
// 1
scnView.showsStatistics = true
// 2
scnView.allowsCameraControl = true
// 3
scnView.autoenablesDefaultLighting = true
}
第二步:創(chuàng)建一個(gè)SCNScene
func setupScene() {
scnScene = SCNScene()
//給當(dāng)前的SCNView 賦值SCNScene
scnView.scene = scnScene
//設(shè)置背景圖片, GeometryFighter.scnassets是我設(shè)置的一個(gè)資源庫, 存放3D資源的
scnScene.background.contents = "GeometryFighter.scnassets/Textures/Background_Diffuse.png"
}
第三步: 添加一個(gè)SCNCamera
func setupCamera() {
// 1創(chuàng)建一個(gè)節(jié)點(diǎn)
cameraNode = SCNNode()
// 2給相機(jī)節(jié)點(diǎn)賦值相機(jī)
cameraNode.camera = SCNCamera()
// 3設(shè)置視角的位置, x:0,y:0就是中心點(diǎn), z只代表觀察的距離, z越大, 物體越小
cameraNode.position = SCNVector3(x: 0, y: 0, z: 10)
// 4 把相機(jī)的節(jié)點(diǎn)添加到根節(jié)點(diǎn)里面
scnScene.rootNode.addChildNode(cameraNode)
}
此時(shí)運(yùn)行代碼, 看到的是一個(gè)只有背景圖片的場(chǎng)景
接下來, 我們?cè)趫?chǎng)景中畫一個(gè)幾何物體
func spawnShape() {
var geometry:SCNGeometry
//畫一個(gè)立方體
geometry = SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0.0)
//把立方體綁定到節(jié)點(diǎn)
let geometryNode = SCNNode(geometry: geometry)
//把節(jié)點(diǎn)添加到場(chǎng)景
scnScene.rootNode.addChildNode(geometryNode)
}
ok, 在viewDidLoad方法里調(diào)用
override func viewDidLoad() {
super.viewDidLoad()
setupView()
setupScene()
setupCamera()
spawnShape()
}
用手指去放大縮小, 看下效果. 是不是被驚到了, 簡(jiǎn)簡(jiǎn)單單的幾部就完成了一個(gè)立方體的繪制, 包括光照效果.