版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2018.10.20 星期六 |
前言
SceneKit
使用高級場景描述創(chuàng)建3D游戲并將3D內容添加到應用程序怨愤。 輕松添加動畫,物理模擬,粒子效果和逼真的基于物理性的渲染睹欲。接下來這幾篇我們就詳細的解析一下這個框架灼舍。感興趣的看下面幾篇文章吼和。
1. SceneKit框架詳細解析(一) —— 基本概覽(一)
2. SceneKit框架詳細解析(二) —— 基于SceneKit的簡單游戲示例的實現(xiàn)(一)
3. SceneKit框架詳細解析(三) —— 基于SceneKit的簡單游戲示例的實現(xiàn)(二)
開始
在這部分中,您將學習如何通過Scene Kit
物理的強大功能使幾何體移動骑素。
我們開始吧炫乓!
在本教程中,您將使用SceneKit
的物理引擎為您的游戲添加物理献丑。
SceneKit
的物理引擎功能強大末捣,易于使用。 您只需告訴SceneKit您想要應用物理的對象创橄,引擎將從該點接管箩做,模擬重力和碰撞等事物。
在深入將物理學集成到游戲中之前妥畏,您首先需要為項目添加一些game utilities
邦邦。
Introducing the Game Utilities - 介紹游戲工具
game utilities
是專門為您創(chuàng)建的安吁。 它們包括輔助方法,可以處理游戲中的復雜位燃辖。 這讓你專注于游戲玩法鬼店,而不是那些討厭的比特。
在這里加了一些游戲相關的工具黔龟,就不細說了妇智,后面用到會詳細說明。
1. Adding the Game Utilities - 添加游戲工具
要添加游戲實用程序捌锭,只需將GameUtils
文件夾拖放到GeometryFighter
組文件夾下的項目中:
將所有設置保留為默認值俘陷,然后單擊Finish
:
這會將整個GameUtils
文件夾作為一個組導入到您的項目中。 展開此組文件夾观谦,快速查看一些幫助程序方法拉盾。 如果某些代碼對您沒有意義,請不要太擔心豁状。
Physics - 物理
是時候快速狀態(tài)檢查游戲的當前狀態(tài)了捉偏。構建并運行游戲;一個很酷的隨機幾何物體像某種黑暗魔法一樣在空氣中產(chǎn)生泻红。這可能現(xiàn)在看起來不太多夭禽,但很快就會有所改善!
剛剛產(chǎn)生的物體只是掛在空曠的空間里并沒有做太多谊路。當然讹躯,你可以圍繞它旋轉相機并放大和縮小,但也就是只能這樣缠劝。這不是一個有趣的游戲潮梯。為了提高興奮程度,如果物體至少移動一點惨恭,那就太好了秉馏。
現(xiàn)在,你可以走很長的路脱羡,并隨著時間的推移操縱對象的位置和旋轉萝究,以便旋轉和移動。您很快就會意識到雖然可以以這種方式為對象設置動畫锉罐,但它需要大量的編碼工作 - 尤其是當您添加其他功能(如真實碰撞和對象之間的交互)時帆竹。
值得慶幸的是,Apple的開發(fā)人員已經(jīng)考慮過這一點氓鄙;為此馆揉,他們將一個非常強大的3D物理引擎集成到SceneKit
中。要使用這個內置的物理引擎抖拦,您只需要讓引擎知道您的對象升酣。
以將幾何信息附加到節(jié)點的方式相同舷暮,可以將physics body
附加到節(jié)點。物理主體描述了節(jié)點的所有物理屬性噩茄,包括形狀下面,質量,摩擦绩聘,阻尼和恢復等內容沥割。物理引擎在模擬對象的真實物理交互時會考慮所有這些信息。這包括重力凿菩,摩擦和物理世界中其他物體碰撞等事物机杜。
下一節(jié)將詳細介紹物理機構的一些重要特征。
1. Physics Body Types - 物理體類型
創(chuàng)建物理主體時必須指定的關鍵屬性之一是其類型(type)
衅谷。物理體類型定義了物體如何與模擬中的力和其他物體相互作用椒拗。
SceneKit
中使用了三種類型:
- 靜態(tài)
(Static)
物體不會移動:當其他物體可能與這些物體碰撞時,靜態(tài)物體本身不受模擬中任何力和碰撞的影響获黔。您可以將此類型用于墻壁和巨大的固定巨石等物體蚀苛。 - 動態(tài)
(Dynamic)
物體由物理引擎自動移動以響應力和碰撞。您可以將此類型用于可移動椅子玷氏,桌子和杯子等物品堵未。 - 物理引擎不會自動移動運動
(Kinematic)
物體以響應力和碰撞。換句話說盏触,如果運動物體與動態(tài)(dynamic)
物體碰撞渗蟹,動態(tài)物體將會移動,但運動物體不會移動赞辩。但是拙徽,您可以在代碼中手動移動運動體。您可以將此類型用于手動控制的內容诗宣,例如移動電梯或可以打開和關閉的門。
2. Physics Shapes - 物理形狀
除了物體的類型之外想诅,在創(chuàng)建物理主體時必須指定的另一個導入屬性是其形狀(shape)
召庞。 物理形狀定義物理引擎在碰撞檢測期間使用的3D形狀。 雖然幾何定義了節(jié)點的視覺效果来破,但物理主體定義了節(jié)點如何與物理模擬中的其他對象進行交互篮灼。
您可以使形狀(shape)
與視覺幾何形狀完全相同,但這通常比您需要的計算成本更高(因此導致您的游戲運行速度變慢)徘禁。 相反诅诱,您通常應該使用幾何體的簡化版本,例如簡單的邊界框送朱,球體或其中一個提供的原始形狀娘荡,大致匹配節(jié)點的可見外觀干旁,如下所示:
3. Adding Physics - 添加物理
現(xiàn)在你已經(jīng)學會了物理背后的理論,現(xiàn)在是時候開始使用這些概念來改變游戲中的事物了炮沐。
在SceneKit中争群,所有物理實體都是SCNPhysicsBody
對象。 創(chuàng)建物理主體后大年,可以將其分配給SCNNode
實例的physicsBody
屬性换薄。 一旦將物理主體分配給適當?shù)墓?jié)點,物理引擎就可以為您模擬物理翔试。 就這么簡單轻要!
打開GameViewController.swift
并在spawnShape()
中創(chuàng)建geometryNode
的代碼行之后添加以下內容:
geometryNode.physicsBody =
SCNPhysicsBody(type: .dynamic, shape: nil)
這行代碼創(chuàng)建了SCNPhysicsBody
的新實例,并將其分配給geometryNode
的physicsBody
屬性垦缅。 創(chuàng)建物理實體時冲泥,可以指定實體的類型和形狀。 如果為物理形狀傳遞nil
失都,SceneKit
將根據(jù)節(jié)點的可視幾何體自動生成形狀柏蘑。
如果要向物理形狀添加更多細節(jié),可以創(chuàng)建SCNPhysicsShape
并將其用于形狀而不是傳入nil
粹庞。
構建并運行您的游戲; 一個隨機的形狀產(chǎn)生進入場景咳焚,然后以死鳥的所有優(yōu)雅的方式從空中掉落,掉出視線:
您甚至可以平移相機以觀察物體庞溜。 你在這里看到的是重力作用于物體的影響革半。 SceneKit中的場景默認情況下重力打開。 現(xiàn)在生成的對象具有物理主體流码,物理模擬將模擬力(例如重力)應用于對象又官。
Forces - 力
想一想現(xiàn)實生活中的物體:做一些移動的東西 - 比如桌子上的勺子 - 你必須對它施加某種類型的物理力。
SceneKit物理引擎在模擬真實物理方面做得相當不錯漫试,所以就像你在現(xiàn)實生活中使用力來移動物體一樣六敬,你需要在你的物理體上施加一個力來移動物體。
當你將力施加到一個物理體驾荣,你用applyForce(direction: at: asImpulse:)
并傳遞一個SCNVector3
實例外构。可以獲得你要施加力時候的力和位置播掷,您施加的力會影響物理體的線性加速度和角加速度审编。
沖擊(impulse)
僅將力施加到物理體上,例如當你踢球時歧匈。物理模擬中的每一步都應用非沖擊力垒酬。 SceneKit
將在對象上添加所有施加的力,并根據(jù)這些力的最終結果加速物理體。這可以模擬類似于助推火箭的東西勘究,其中力是連續(xù)的矮湘。
之前,您了解到力是具有x乱顾,y和z分量的向量板祝。但是,這是什么意思走净?看看下圖:
力具有大小和方向券时,因此矢量確定每個軸的力的大小。 在上面的示例中伏伯,應用具有(x:0橘洞,y:10,z:0)
向量的力可以使用垂直力向上移動主體说搅。
要應用水平力炸枣,您只能使用(x:10,y:0弄唧,z:0)
的向量指定x軸上的力的大小适肠。 要向左移動而不是向右移動,您將在x軸上施加負的力大小候引。 當您將各種矢量組合在一起時(x:10侯养,y:10,z:0)
澄干,您可以準確控制身體的移動方式 - 在這種情況下逛揩,對角線。
力也可以應用于物理體的特定位置以產(chǎn)生不同的運動:
同樣麸俘,它有助于思考現(xiàn)實生活中的例子辩稽。 如果你前面有一個擋塊并推動它,擋塊會根據(jù)你施加推動的位置而有所不同从媚。 將相同的力施加到身體質心的左側或右側逞泄,例如,在(x:1拜效,y:0炭懊,z:0)
處將使其旋轉。在(x:0拂檩,y:0,z:0)
處直接施加與質心一致的力將不會產(chǎn)生旋轉嘲碧。
1. Applying Force - 施力
卷起你的袖子 - 是時候施加一些力量了稻励!
在spawnShape()
中為geometryNode
創(chuàng)建物理體的行之后添加以下代碼:
// 1
let randomX = Float.random(min: -2, max: 2)
let randomY = Float.random(min: 10, max: 18)
// 2
let force = SCNVector3(x: randomX, y: randomY , z: 0)
// 3
let position = SCNVector3(x: 0.05, y: 0.05, z: 0.05)
// 4
geometryNode.physicsBody?.applyForce(force,
at: position, asImpulse: true)
下面進行詳細說明:
- 1) 這將創(chuàng)建兩個隨機浮點值,表示力的x和y分量。 它使用您在本教程前面添加的實用程序的
Float
擴展望抽。 - 2) 接下來,使用這些隨機組件創(chuàng)建一個向量來表示此力。
- 3) 這將創(chuàng)建另一個向量程癌,表示力將應用到的位置璧诵。 該位置稍微偏離中心,以便在物體上產(chǎn)生旋轉辑奈。
- 4) 最后苛茂,使用所有這些組件,使用
applyForce(direction:at:asImpulse :)
將力應用于geometryNode
的物理體鸠窗。
構建并運行妓羊;當物體憑空產(chǎn)生時,一些神奇的力量將它踢向空中稍计,而不是像死鳥一樣掉落:
當重力作用時躁绸,物體最終會落下。
Torque - 扭力
扭矩是另一種可以使用applyTorque(torque: asImpulse:)
應用于物體的旋轉力臣嚣。 扭矩僅影響物理體的角動量(自旋)净刮,而不影響線性動量(x,y硅则,z)淹父。 施加扭矩導致物體圍繞其質心旋轉。
要了解扭矩如何影響物理機構抢埋,請查看下圖:
應用扭矩力時弹灭,使用SCNVector4
指定四分量矢量,而不是像使用力一樣使用三分量矢量揪垄。 x穷吮,y和z分量確定旋轉軸,而w分量確定旋轉角度饥努,即扭矩的大小捡鱼。
就像使用applyForce(direction:at:asImpulse :)
一樣,您可以選擇是否將扭矩應用為沖擊酷愧,這會影響物理引擎處理矢量的方式驾诈。
如果扭矩是沖擊,則方向矢量被視為角動量的瞬時變化溶浴。想想用手指旋轉籃球乍迄;為了保持球的旋轉,你必須用你的手快速揮動球的一側士败,每次輕彈都會產(chǎn)生一個沖擊闯两,瞬間增加球的角動量褥伴。
當扭矩不作為沖擊施加時,它在每個物理模擬步驟之后應用漾狼。 SceneKit將對所有施加的力和扭矩求和重慢,并根據(jù)這些力的凈效應加速物理體的角力⊙吩辏可以把它想象成一個圍繞自己的軸以恒定速度旋轉的行星似踱。
注意:SceneKit物理模擬使用國際單位系統(tǒng)
(SI)
進行測量:質量單位的公斤數(shù),力單位的牛頓稽煤,脈沖(impulse)
單位的牛頓秒和扭矩單位的牛頓米核芽。
Adding Flair - 添加Flair
既然你已經(jīng)移動了幾何物體,你可能已經(jīng)注意到它在屏幕中間的空氣中產(chǎn)生念脯,這看起來有點尷尬狞洋。 為了解決這個問題,你可以將相機在y軸上移動一點绿店,這樣物體就會在屏幕外產(chǎn)生吉懊。
1. Positioning the Camera - 定位相機
要向上移動攝像機位置,請使用以下內容替換在setupCamera()
中設置攝像機位置的行:
cameraNode.position = SCNVector3(x: 0, y: 5, z: 10)
構建并運行假勿,您將看到該對象似乎在屏幕外生成借嗽!
2. Adding some Color - 添加一些顏色
最后,您可以為隨機生成的形狀添加一些變化转培。
在spawnShape()
中添加以下幾行恶导,在您隨機創(chuàng)建geometry
的位置之后,但在創(chuàng)建geometryNode
之前:
geometry.materials.first?.diffuse.contents = UIColor.random()
要為隨機對象著色浸须,可以修改geometry
上的materials
惨寿;此行獲取幾何體的第一個可用材質,并將diffuse
屬性的內容設置為隨機UIColor
删窒。 UIColor上的random()
方法是另一個被定義為game utilities
內部擴展的助手裂垦。
注意:這里需要注意的是,您可以為漫反射
(diffuse )
屬性的內容指定UIColor
肌索,以便更改對象的顏色蕉拢。
最后,構建并運行游戲以查看顏色漂亮的對象:
后記
本篇主要講述了基于SceneKit的簡單游戲示例的實現(xiàn)诚亚,感興趣的給個贊或者關注~~~